Add text-transform attribute to the style block

This provides an option to override the functionality provided by the
theme, or apply `text-transform` outside of the theme.

The functionality of the `text-transform` is as below:

- `text-transform: none` - will disable **any** transformation (like the uppercasing by `terminal` theme)
- `text-transform: uppercase` (uppercase not upper as per your message) - will force all characters into uppercase.
- `text-transform: lowercase` - will force all characters into lowercase.
- `text-transform: capitalize` - will uppercase the first letter of every word

In addition, this commit introduces:
- helper methods on the `d2graph.Style` struct to determine the type of
  `text-transform` to be applied.
- `ApplyTextTransform` method on the `d2graph.Attributes` which will
  transform the `Label.Value` to the correct text case.
This commit is contained in:
Stoica Alex 2023-03-31 09:58:02 +01:00
parent 9692e47525
commit a260068d2c
No known key found for this signature in database
GPG key ID: 221CE76471A10868
17 changed files with 1328 additions and 1171 deletions

View file

@ -9,6 +9,7 @@
- Labels on parallel `dagre` connections include a gap between them [#1134](https://github.com/terrastruct/d2/pull/1134)
- Sequence Diagram `Lifelines` now inherit the Actor `stroke` and `stroke-dash` [#1140](https://github.com/terrastruct/d2/pull/1140)
- Add `text-transform` styling option [#1118](https://github.com/terrastruct/d2/pull/1118)
#### Bugfixes ⛑️

View file

@ -500,6 +500,8 @@ func compileStyleFieldInit(attrs *d2graph.Attributes, f *d2ir.Field) {
attrs.Left = &d2graph.Scalar{MapKey: f.LastPrimaryKey()}
case "double-border":
attrs.Style.DoubleBorder = &d2graph.Scalar{MapKey: f.LastPrimaryKey()}
case "text-transform":
attrs.Style.TextTransform = &d2graph.Scalar{MapKey: f.LastPrimaryKey()}
}
}

View file

@ -10,6 +10,9 @@ import (
"strconv"
"strings"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"oss.terrastruct.com/util-go/go2"
"oss.terrastruct.com/d2/d2ast"
@ -141,6 +144,25 @@ type Attributes struct {
Classes []string `json:"classes,omitempty"`
}
// ApplyTextTransform will alter the `Label.Value` of the current object based
// on the specification of the `text-transform` styling option. This function
// has side-effects!
func (a *Attributes) ApplyTextTransform() {
if a.Style.NoneTextTransform() {
return
}
if a.Style.TextTransform != nil && a.Style.TextTransform.Value == "uppercase" {
a.Label.Value = strings.ToUpper(a.Label.Value)
}
if a.Style.TextTransform != nil && a.Style.TextTransform.Value == "lowercase" {
a.Label.Value = strings.ToLower(a.Label.Value)
}
if a.Style.TextTransform != nil && a.Style.TextTransform.Value == "capitalize" {
a.Label.Value = cases.Title(language.Und).String(a.Label.Value)
}
}
// TODO references at the root scope should have their Scope set to root graph AST
type Reference struct {
Key *d2ast.KeyPath `json:"key"`
@ -161,25 +183,33 @@ func (r Reference) InEdge() bool {
}
type Style struct {
Opacity *Scalar `json:"opacity,omitempty"`
Stroke *Scalar `json:"stroke,omitempty"`
Fill *Scalar `json:"fill,omitempty"`
FillPattern *Scalar `json:"fillPattern,omitempty"`
StrokeWidth *Scalar `json:"strokeWidth,omitempty"`
StrokeDash *Scalar `json:"strokeDash,omitempty"`
BorderRadius *Scalar `json:"borderRadius,omitempty"`
Shadow *Scalar `json:"shadow,omitempty"`
ThreeDee *Scalar `json:"3d,omitempty"`
Multiple *Scalar `json:"multiple,omitempty"`
Font *Scalar `json:"font,omitempty"`
FontSize *Scalar `json:"fontSize,omitempty"`
FontColor *Scalar `json:"fontColor,omitempty"`
Animated *Scalar `json:"animated,omitempty"`
Bold *Scalar `json:"bold,omitempty"`
Italic *Scalar `json:"italic,omitempty"`
Underline *Scalar `json:"underline,omitempty"`
Filled *Scalar `json:"filled,omitempty"`
DoubleBorder *Scalar `json:"doubleBorder,omitempty"`
Opacity *Scalar `json:"opacity,omitempty"`
Stroke *Scalar `json:"stroke,omitempty"`
Fill *Scalar `json:"fill,omitempty"`
FillPattern *Scalar `json:"fillPattern,omitempty"`
StrokeWidth *Scalar `json:"strokeWidth,omitempty"`
StrokeDash *Scalar `json:"strokeDash,omitempty"`
BorderRadius *Scalar `json:"borderRadius,omitempty"`
Shadow *Scalar `json:"shadow,omitempty"`
ThreeDee *Scalar `json:"3d,omitempty"`
Multiple *Scalar `json:"multiple,omitempty"`
Font *Scalar `json:"font,omitempty"`
FontSize *Scalar `json:"fontSize,omitempty"`
FontColor *Scalar `json:"fontColor,omitempty"`
Animated *Scalar `json:"animated,omitempty"`
Bold *Scalar `json:"bold,omitempty"`
Italic *Scalar `json:"italic,omitempty"`
Underline *Scalar `json:"underline,omitempty"`
Filled *Scalar `json:"filled,omitempty"`
DoubleBorder *Scalar `json:"doubleBorder,omitempty"`
TextTransform *Scalar `json:"textTransform,omitempty"`
}
// NoneTextTransform will return a boolean if the text should not have any
// transformation applied. This should overwrite theme specific transformations
// like `CapsLock` from the `terminal` theme.
func (s Style) NoneTextTransform() bool {
return s.TextTransform != nil && s.TextTransform.Value == "none"
}
func (s *Style) Apply(key, value string) error {
@ -350,6 +380,14 @@ func (s *Style) Apply(key, value string) error {
return errors.New(`expected "double-border" to be true or false`)
}
s.DoubleBorder.Value = value
case "text-transform":
if s.TextTransform == nil {
break
}
if !go2.Contains(textTransforms, strings.ToLower(value)) {
return fmt.Errorf(`expected "text-transform" to be one of (%s)`, strings.Join(textTransforms, ","))
}
s.TextTransform.Value = value
default:
return fmt.Errorf("unknown style key: %s", key)
}
@ -1329,10 +1367,11 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
}
if g.Theme != nil && g.Theme.SpecialRules.CapsLock && !strings.EqualFold(obj.Attributes.Shape.Value, d2target.ShapeCode) {
if obj.Attributes.Language != "latex" {
if obj.Attributes.Language != "latex" && !obj.Attributes.Style.NoneTextTransform() {
obj.Attributes.Label.Value = strings.ToUpper(obj.Attributes.Label.Value)
}
}
obj.Attributes.ApplyTextTransform()
labelDims, err := obj.GetLabelSize(mtexts, ruler, fontFamily)
if err != nil {
@ -1451,9 +1490,11 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
continue
}
if g.Theme != nil && g.Theme.SpecialRules.CapsLock {
if g.Theme != nil && g.Theme.SpecialRules.CapsLock && !edge.Attributes.Style.NoneTextTransform() {
edge.Attributes.Label.Value = strings.ToUpper(edge.Attributes.Label.Value)
}
edge.Attributes.ApplyTextTransform()
usedFont := fontFamily
if edge.Attributes.Style.Font != nil {
f := d2fonts.D2_FONT_TO_FAMILY[edge.Attributes.Style.Font.Value]
@ -1479,9 +1520,10 @@ func (g *Graph) Texts() []*d2target.MText {
for _, obj := range g.Objects {
if obj.Attributes.Label.Value != "" {
obj.Attributes.ApplyTextTransform()
text := obj.Text()
if capsLock && !strings.EqualFold(obj.Attributes.Shape.Value, d2target.ShapeCode) {
if obj.Attributes.Language != "latex" {
if obj.Attributes.Language != "latex" && !obj.Attributes.Style.NoneTextTransform() {
text.Text = strings.ToUpper(text.Text)
}
}
@ -1512,8 +1554,9 @@ func (g *Graph) Texts() []*d2target.MText {
}
for _, edge := range g.Edges {
if edge.Attributes.Label.Value != "" {
edge.Attributes.ApplyTextTransform()
text := edge.Text()
if capsLock {
if capsLock && !edge.Attributes.Style.NoneTextTransform() {
text.Text = strings.ToUpper(text.Text)
}
texts = appendTextDedup(texts, text)
@ -1625,6 +1668,8 @@ var FillPatterns = []string{
"paper",
}
var textTransforms = []string{"none", "uppercase", "lowercase", "capitalize"}
// BoardKeywords contains the keywords that create new boards.
var BoardKeywords = map[string]struct{}{
"layers": {},

View file

@ -10,7 +10,7 @@
"x": 0,
"y": 275
},
"width": 399,
"width": 403,
"height": 1225,
"opacity": 1,
"strokeDash": 0,
@ -52,7 +52,7 @@
"x": 95,
"y": 340
},
"width": 284,
"width": 288,
"height": 317,
"opacity": 1,
"strokeDash": 0,
@ -73,7 +73,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "cell tower",
"label": "Cell Tower",
"fontSize": 24,
"fontFamily": "DEFAULT",
"language": "",
@ -81,7 +81,7 @@
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelWidth": 106,
"labelHeight": 31,
"labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0,
@ -91,7 +91,7 @@
"id": "network.cell tower.satellites",
"type": "stored_data",
"pos": {
"x": 185,
"x": 187,
"y": 372
},
"width": 104,
@ -133,7 +133,7 @@
"id": "network.cell tower.transmitter",
"type": "rectangle",
"pos": {
"x": 185,
"x": 187,
"y": 559
},
"width": 104,
@ -259,7 +259,7 @@
"id": "network.data processor",
"type": "rectangle",
"pos": {
"x": 145,
"x": 147,
"y": 814
},
"width": 184,
@ -301,7 +301,7 @@
"id": "network.data processor.storage",
"type": "cylinder",
"pos": {
"x": 185,
"x": 187,
"y": 846
},
"width": 104,
@ -343,7 +343,7 @@
"id": "user",
"type": "person",
"pos": {
"x": 80,
"x": 81,
"y": 0
},
"width": 130,
@ -381,14 +381,56 @@
"zIndex": 0,
"level": 1
},
{
"id": "other-user",
"type": "person",
"pos": {
"x": 271,
"y": 8
},
"width": 108,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "B3",
"fillPattern": "paper",
"stroke": "B1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "OTHER-USER",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 93,
"labelHeight": 21,
"labelPosition": "OUTSIDE_BOTTOM_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "api server",
"type": "rectangle",
"pos": {
"x": 439,
"x": 443,
"y": 1076
},
"width": 153,
"width": 151,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@ -409,7 +451,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "API サーバー",
"label": "api サーバー",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
@ -417,7 +459,7 @@
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 108,
"labelWidth": 106,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
@ -427,7 +469,7 @@
"id": "logs",
"type": "page",
"pos": {
"x": 474,
"x": 477,
"y": 1313
},
"width": 84,
@ -493,19 +535,19 @@
"labelPercentage": 0,
"route": [
{
"x": 211,
"x": 212,
"y": 439
},
{
"x": 173.4,
"x": 173.6,
"y": 487
},
{
"x": 173.4,
"x": 173.8,
"y": 511.2
},
{
"x": 211,
"x": 213,
"y": 560
}
],
@ -527,7 +569,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "send",
"label": "SEND",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
@ -535,25 +577,25 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 33,
"labelWidth": 37,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 237,
"x": 239,
"y": 439
},
{
"x": 237,
"x": 239,
"y": 487
},
{
"x": 237,
"x": 239,
"y": 511.2
},
{
"x": 237,
"x": 239,
"y": 560
}
],
@ -589,19 +631,19 @@
"labelPercentage": 0,
"route": [
{
"x": 263,
"x": 266,
"y": 439
},
{
"x": 300.6,
"x": 304.4,
"y": 487
},
{
"x": 300.6,
"x": 304.2,
"y": 511.2
},
{
"x": 263,
"x": 265,
"y": 560
}
],
@ -637,31 +679,31 @@
"labelPercentage": 0,
"route": [
{
"x": 237,
"x": 239,
"y": 625.5
},
{
"x": 237,
"x": 239,
"y": 651.1
},
{
"x": 237,
"x": 239,
"y": 669.6
},
{
"x": 237,
"x": 239,
"y": 687.75
},
{
"x": 237,
"x": 239,
"y": 705.9
},
{
"x": 237,
"x": 239,
"y": 792.2
},
{
"x": 237,
"x": 239,
"y": 847
}
],
@ -697,19 +739,19 @@
"labelPercentage": 0,
"route": [
{
"x": 169,
"x": 170,
"y": 87
},
{
"x": 223.4,
"x": 225.2,
"y": 156.2
},
{
"x": 237,
"x": 239,
"y": 248.2
},
{
"x": 237,
"x": 239,
"y": 305
}
],
@ -745,11 +787,11 @@
"labelPercentage": 0,
"route": [
{
"x": 126,
"x": 127,
"y": 87
},
{
"x": 85,
"x": 85.19999999999999,
"y": 156.2
},
{
@ -949,12 +991,12 @@
"labelPercentage": 0,
"route": [
{
"x": 439.25,
"y": 1127.0397225725094
"x": 443.25,
"y": 1126.6702127659576
},
{
"x": 183.25,
"y": 1187.4079445145019
"x": 184.05,
"y": 1187.3340425531915
},
{
"x": 116,
@ -997,19 +1039,19 @@
"labelPercentage": 0,
"route": [
{
"x": 515.75,
"x": 518.75,
"y": 1142
},
{
"x": 515.75,
"x": 518.75,
"y": 1190.4
},
{
"x": 515.8,
"x": 518.8,
"y": 1273
},
{
"x": 516,
"x": 519,
"y": 1313
}
],
@ -1045,20 +1087,20 @@
"labelPercentage": 0,
"route": [
{
"x": 237,
"x": 239,
"y": 996.5
},
{
"x": 237,
"x": 239,
"y": 1020.1
},
{
"x": 277.4,
"y": 1038
"x": 279.8,
"y": 1038.2
},
{
"x": 439,
"y": 1086
"x": 443,
"y": 1087
}
],
"isCurve": true,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 455 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View file

@ -10,7 +10,7 @@
"x": 12,
"y": 311
},
"width": 690,
"width": 692,
"height": 902,
"opacity": 1,
"strokeDash": 0,
@ -49,10 +49,10 @@
"id": "network.cell tower",
"type": "rectangle",
"pos": {
"x": 94,
"x": 92,
"y": 361
},
"width": 222,
"width": 226,
"height": 413,
"opacity": 1,
"strokeDash": 0,
@ -73,7 +73,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "cell tower",
"label": "Cell Tower",
"fontSize": 24,
"fontFamily": "DEFAULT",
"language": "",
@ -81,7 +81,7 @@
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelWidth": 106,
"labelHeight": 31,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
@ -175,7 +175,7 @@
"id": "network.online portal",
"type": "rectangle",
"pos": {
"x": 336,
"x": 338,
"y": 366
},
"width": 316,
@ -217,7 +217,7 @@
"id": "network.online portal.ui",
"type": "hexagon",
"pos": {
"x": 454,
"x": 456,
"y": 416
},
"width": 80,
@ -343,7 +343,7 @@
"id": "user",
"type": "person",
"pos": {
"x": 341,
"x": 343,
"y": 12
},
"width": 130,
@ -381,14 +381,56 @@
"zIndex": 0,
"level": 1
},
{
"id": "other-user",
"type": "person",
"pos": {
"x": 511,
"y": 19
},
"width": 108,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "B3",
"fillPattern": "paper",
"stroke": "B1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "OTHER-USER",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 93,
"labelHeight": 21,
"labelPosition": "OUTSIDE_BOTTOM_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "api server",
"type": "rectangle",
"pos": {
"x": 666,
"x": 669,
"y": 59
},
"width": 153,
"width": 151,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@ -409,7 +451,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "API サーバー",
"label": "api サーバー",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
@ -417,7 +459,7 @@
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 108,
"labelWidth": 106,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
@ -427,7 +469,7 @@
"id": "logs",
"type": "page",
"pos": {
"x": 782,
"x": 784,
"y": 311
},
"width": 84,
@ -493,11 +535,11 @@
"labelPercentage": 0,
"route": [
{
"x": 161,
"x": 159,
"y": 477
},
{
"x": 161,
"x": 159,
"y": 658
}
],
@ -518,7 +560,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "send",
"label": "SEND",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
@ -526,7 +568,7 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 33,
"labelWidth": 37,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
@ -571,11 +613,11 @@
"labelPercentage": 0,
"route": [
{
"x": 249,
"x": 251,
"y": 477
},
{
"x": 249,
"x": 251,
"y": 658
}
],
@ -649,19 +691,19 @@
"labelPercentage": 0,
"route": [
{
"x": 385,
"x": 387,
"y": 99
},
{
"x": 384.5833333333333,
"x": 386.5833333333333,
"y": 165
},
{
"x": 259.3333333333333,
"x": 260.3333333333333,
"y": 165
},
{
"x": 259.3333333333333,
"x": 260.3333333333333,
"y": 361
}
],
@ -696,19 +738,19 @@
"labelPercentage": 0,
"route": [
{
"x": 428,
"x": 430,
"y": 99
},
{
"x": 427.91666666666663,
"x": 429.91666666666663,
"y": 165
},
{
"x": 481.16666666666663,
"x": 483.16666666666663,
"y": 165
},
{
"x": 481,
"x": 483,
"y": 416
}
],
@ -743,19 +785,19 @@
"labelPercentage": 0,
"route": [
{
"x": 704.25,
"x": 706.75,
"y": 125
},
{
"x": 704.25,
"x": 706.75,
"y": 266
},
{
"x": 507.83333333333337,
"x": 509.83333333333337,
"y": 266
},
{
"x": 508,
"x": 510,
"y": 416
}
],
@ -790,19 +832,19 @@
"labelPercentage": 0,
"route": [
{
"x": 780.75,
"x": 782.25,
"y": 125
},
{
"x": 780.75,
"x": 782.25,
"y": 165
},
{
"x": 824.5,
"x": 826.5,
"y": 165
},
{
"x": 825,
"x": 827,
"y": 311
}
],
@ -845,11 +887,11 @@
"y": 1258
},
{
"x": 742.5,
"x": 744.5,
"y": 1258
},
{
"x": 742.5,
"x": 744.5,
"y": 125
}
],

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 454 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View file

@ -10,7 +10,7 @@
"x": 0,
"y": 438
},
"width": 499,
"width": 500,
"height": 1565,
"opacity": 1,
"strokeDash": 0,
@ -52,7 +52,7 @@
"x": 96,
"y": 503
},
"width": 383,
"width": 384,
"height": 657,
"opacity": 1,
"strokeDash": 0,
@ -73,7 +73,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "CELL TOWER",
"label": "Cell Tower",
"fontSize": 24,
"fontFamily": "mono",
"language": "",
@ -81,7 +81,7 @@
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 143,
"labelWidth": 142,
"labelHeight": 31,
"labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0,
@ -256,7 +256,7 @@
"id": "network.data processor",
"type": "rectangle",
"pos": {
"x": 220,
"x": 221,
"y": 1317
},
"width": 192,
@ -298,7 +298,7 @@
"id": "network.data processor.storage",
"type": "cylinder",
"pos": {
"x": 260,
"x": 261,
"y": 1349
},
"width": 112,
@ -840,7 +840,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "SEND",
"label": "send",
"fontSize": 16,
"fontFamily": "mono",
"language": "",
@ -848,7 +848,7 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 38,
"labelWidth": 39,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
@ -858,15 +858,15 @@
"y": 772
},
{
"x": 185.8,
"x": 186,
"y": 956
},
{
"x": 196.3,
"x": 196.55,
"y": 1014.2
},
{
"x": 267.5,
"x": 267.75,
"y": 1063
}
],
@ -906,15 +906,15 @@
"y": 772
},
{
"x": 250.2,
"x": 250.8,
"y": 956
},
{
"x": 264.3,
"x": 264.85,
"y": 1014.2
},
{
"x": 295.5,
"x": 295.25,
"y": 1063
}
],
@ -954,15 +954,15 @@
"y": 772
},
{
"x": 366.4,
"x": 367,
"y": 956
},
{
"x": 386.65,
"x": 387.4,
"y": 1014.2
},
{
"x": 344.25,
"x": 345,
"y": 1063
}
],
@ -998,31 +998,31 @@
"labelPercentage": 0,
"route": [
{
"x": 316,
"x": 316.5,
"y": 1128.5
},
{
"x": 316,
"x": 316.5,
"y": 1154.1
},
{
"x": 316,
"x": 316.5,
"y": 1172.6
},
{
"x": 316,
"x": 316.5,
"y": 1190.75
},
{
"x": 316,
"x": 316.5,
"y": 1208.9
},
{
"x": 316,
"x": 316.6,
"y": 1295.2
},
{
"x": 316,
"x": 317,
"y": 1350
}
],
@ -1062,15 +1062,15 @@
"y": 169
},
{
"x": 208.2,
"x": 208.6,
"y": 303
},
{
"x": 220,
"x": 220.5,
"y": 411.2
},
{
"x": 220,
"x": 220.5,
"y": 468
}
],
@ -1106,11 +1106,11 @@
"labelPercentage": 0,
"route": [
{
"x": 138,
"x": 139,
"y": 169
},
{
"x": 88.6,
"x": 88.8,
"y": 303
},
{
@ -1310,12 +1310,12 @@
"labelPercentage": 0,
"route": [
{
"x": 539.5,
"y": 1625.8374153204795
"x": 540.25,
"y": 1625.8158168574403
},
{
"x": 212.5,
"y": 1689.567483064096
"x": 212.64999999999998,
"y": 1689.5631633714881
},
{
"x": 127.4,
@ -1358,15 +1358,15 @@
"labelPercentage": 0,
"route": [
{
"x": 610.5,
"x": 611.25,
"y": 1645
},
{
"x": 610.5,
"x": 611.25,
"y": 1693.4
},
{
"x": 610.6,
"x": 611.2,
"y": 1776
},
{
@ -1406,20 +1406,20 @@
"labelPercentage": 0,
"route": [
{
"x": 316,
"x": 316.5,
"y": 1499.5
},
{
"x": 316,
"x": 316.5,
"y": 1523.1
},
{
"x": 360.7,
"y": 1541.5979626485569
"x": 361.3,
"y": 1541.6
},
{
"x": 539.5,
"y": 1591.9898132427843
"x": 540.5,
"y": 1592
}
],
"isCurve": true,
@ -1454,31 +1454,31 @@
"labelPercentage": 0,
"route": [
{
"x": 973.5,
"x": 974.25,
"y": 198.5
},
{
"x": 973.5,
"x": 974.25,
"y": 308.9
},
{
"x": 973.5,
"x": 974.25,
"y": 348.6
},
{
"x": 973.5,
"x": 974.25,
"y": 366.75
},
{
"x": 973.5,
"x": 974.25,
"y": 384.9
},
{
"x": 973.5,
"x": 974.25,
"y": 457
},
{
"x": 973.5,
"x": 974.25,
"y": 497
}
],
@ -1514,19 +1514,19 @@
"labelPercentage": 0,
"route": [
{
"x": 973.5,
"x": 974.25,
"y": 903
},
{
"x": 973.5,
"x": 974.25,
"y": 951.4
},
{
"x": 973.5,
"x": 974.25,
"y": 977.1
},
{
"x": 973.5,
"x": 974.25,
"y": 1031.5
}
],

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -73,7 +73,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "CELL TOWER",
"label": "Cell Tower",
"fontSize": 24,
"fontFamily": "mono",
"language": "",
@ -81,7 +81,7 @@
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 143,
"labelWidth": 142,
"labelHeight": 31,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
@ -840,7 +840,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "SEND",
"label": "send",
"fontSize": 16,
"fontFamily": "mono",
"language": "",
@ -848,7 +848,7 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 38,
"labelWidth": 39,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
@ -858,7 +858,7 @@
"y": 1075
},
{
"x": 143.5,
"x": 143.25,
"y": 1256
}
],
@ -893,11 +893,11 @@
"labelPercentage": 0,
"route": [
{
"x": 192,
"x": 193,
"y": 1075
},
{
"x": 192.5,
"x": 192.75,
"y": 1256
}
],
@ -932,11 +932,11 @@
"labelPercentage": 0,
"route": [
{
"x": 241,
"x": 242,
"y": 1075
},
{
"x": 241.5,
"x": 241.75,
"y": 1256
}
],

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -10,7 +10,7 @@
"x": 0,
"y": 275
},
"width": 436,
"width": 437,
"height": 1225,
"opacity": 1,
"strokeDash": 0,
@ -52,7 +52,7 @@
"x": 96,
"y": 340
},
"width": 320,
"width": 321,
"height": 317,
"opacity": 1,
"strokeDash": 0,
@ -73,7 +73,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "CELL TOWER",
"label": "Cell Tower",
"fontSize": 24,
"fontFamily": "mono",
"language": "",
@ -81,7 +81,7 @@
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 143,
"labelWidth": 142,
"labelHeight": 31,
"labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0,
@ -91,7 +91,7 @@
"id": "network.cell tower.satellites",
"type": "stored_data",
"pos": {
"x": 176,
"x": 177,
"y": 372
},
"width": 161,
@ -132,7 +132,7 @@
"id": "network.cell tower.transmitter",
"type": "rectangle",
"pos": {
"x": 181,
"x": 182,
"y": 559
},
"width": 151,
@ -380,7 +380,7 @@
"id": "api server",
"type": "rectangle",
"pos": {
"x": 477,
"x": 478,
"y": 1076
},
"width": 142,
@ -421,7 +421,7 @@
"id": "logs",
"type": "page",
"pos": {
"x": 507,
"x": 508,
"y": 1313
},
"width": 82,
@ -472,7 +472,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "SEND",
"label": "send",
"fontSize": 16,
"fontFamily": "mono",
"language": "",
@ -480,7 +480,7 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 38,
"labelWidth": 39,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
@ -490,15 +490,15 @@
"y": 439
},
{
"x": 188.6,
"x": 188.8,
"y": 487
},
{
"x": 188.5,
"x": 188.95,
"y": 511.2
},
{
"x": 228.5,
"x": 229.75,
"y": 560
}
],
@ -534,19 +534,19 @@
"labelPercentage": 0,
"route": [
{
"x": 256,
"x": 257,
"y": 439
},
{
"x": 256.4,
"x": 257.2,
"y": 487
},
{
"x": 256.5,
"x": 257.25,
"y": 511.2
},
{
"x": 256.5,
"x": 257.25,
"y": 560
}
],
@ -582,19 +582,19 @@
"labelPercentage": 0,
"route": [
{
"x": 284,
"x": 285,
"y": 439
},
{
"x": 324.4,
"x": 325.2,
"y": 487
},
{
"x": 324.5,
"x": 325.05,
"y": 511.2
},
{
"x": 284.5,
"x": 284.25,
"y": 560
}
],
@ -616,7 +616,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "PHONE LOGS",
"label": "phone logs",
"fontSize": 16,
"fontFamily": "mono",
"language": "",
@ -624,33 +624,33 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 96,
"labelWidth": 97,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 256.5,
"x": 257,
"y": 625.5
},
{
"x": 256.5,
"x": 257,
"y": 651.1
},
{
"x": 256.5,
"x": 257,
"y": 669.6
},
{
"x": 256.5,
"x": 257,
"y": 687.75
},
{
"x": 256.5,
"x": 257,
"y": 705.9
},
{
"x": 256.6,
"x": 257,
"y": 792.2
},
{
@ -694,15 +694,15 @@
"y": 87
},
{
"x": 240.8,
"x": 241.2,
"y": 156.2
},
{
"x": 256.5,
"x": 257,
"y": 248.2
},
{
"x": 256.5,
"x": 257,
"y": 305
}
],
@ -942,12 +942,12 @@
"labelPercentage": 0,
"route": [
{
"x": 476.75,
"y": 1124.9196642685852
"x": 477.5,
"y": 1124.8910831837222
},
{
"x": 199.95,
"y": 1186.983932853717
"x": 200.09999999999997,
"y": 1186.9782166367445
},
{
"x": 127,
@ -990,19 +990,19 @@
"labelPercentage": 0,
"route": [
{
"x": 547.75,
"x": 548.5,
"y": 1142
},
{
"x": 547.75,
"x": 548.5,
"y": 1190.4
},
{
"x": 547.8,
"x": 548.6,
"y": 1273
},
{
"x": 548,
"x": 549,
"y": 1313
}
],
@ -1038,20 +1038,20 @@
"labelPercentage": 0,
"route": [
{
"x": 256.5,
"x": 257,
"y": 996.5
},
{
"x": 256.5,
"x": 257,
"y": 1020.1
},
{
"x": 300.55,
"y": 1038.5533047210301
"x": 301.1,
"y": 1038.5567753001715
},
{
"x": 476.75,
"y": 1088.7665236051503
"x": 477.5,
"y": 1088.7838765008576
}
],
"isCurve": true,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -73,7 +73,7 @@
"fields": null,
"methods": null,
"columns": null,
"label": "CELL TOWER",
"label": "Cell Tower",
"fontSize": 24,
"fontFamily": "mono",
"language": "",
@ -81,7 +81,7 @@
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 143,
"labelWidth": 142,
"labelHeight": 31,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
@ -472,7 +472,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "SEND",
"label": "send",
"fontSize": 16,
"fontFamily": "mono",
"language": "",
@ -480,7 +480,7 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 38,
"labelWidth": 39,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
@ -490,7 +490,7 @@
"y": 477
},
{
"x": 143.5,
"x": 143.25,
"y": 658
}
],
@ -525,11 +525,11 @@
"labelPercentage": 0,
"route": [
{
"x": 192,
"x": 193,
"y": 477
},
{
"x": 192.5,
"x": 192.75,
"y": 658
}
],
@ -564,11 +564,11 @@
"labelPercentage": 0,
"route": [
{
"x": 241,
"x": 242,
"y": 477
},
{
"x": 241.5,
"x": 241.75,
"y": 658
}
],
@ -589,7 +589,7 @@
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "B1",
"label": "PHONE LOGS",
"label": "phone logs",
"fontSize": 16,
"fontFamily": "mono",
"language": "",
@ -597,7 +597,7 @@
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 96,
"labelWidth": 97,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -15,14 +15,19 @@ func testThemes(t *testing.T) {
script: `
network: {
cell tower: {
style.text-transform: capitalize
satellites: {
shape: stored_data
style.multiple: true
}
transmitter
transmitter : {
style.text-transform: uppercase
}
satellites -> transmitter: send
satellites -> transmitter: SEnD {
style.text-transform: lowercase
}
satellites -> transmitter: send
satellites -> transmitter: send
}
@ -117,6 +122,7 @@ ex: |tex
script: `
network: {
cell tower: {
style.text-transform: capitalize
satellites: {
shape: stored_data
style.multiple: true
@ -124,7 +130,9 @@ network: {
transmitter
satellites -> transmitter: send
satellites -> transmitter: SEnD {
style.text-transform: lowercase
}
satellites -> transmitter: send
satellites -> transmitter: send
}
@ -140,7 +148,9 @@ network: {
}
}
cell tower.transmitter -> data processor.storage: phone logs
cell tower.transmitter -> data processor.storage: phone logs {
style.text-transform: none
}
}
user: {
@ -166,6 +176,7 @@ network.data processor -> api server
script: `
network: 通信網 {
cell tower: {
style.text-transform: capitalize
satellites: 衛星 {
shape: stored_data
style.multiple: true
@ -173,8 +184,12 @@ network: 通信網 {
transmitter: 送信機
satellites -> transmitter: send
satellites -> transmitter: send
satellites -> transmitter: SEnD {
style.text-transform: lowercase
}
satellites -> transmitter: send {
style.text-transform: uppercase
}
satellites -> transmitter: send
}
@ -189,12 +204,20 @@ network: 通信網 {
}
}
cell tower.transmitter -> data processor.storage: 電話ログ
cell tower.transmitter -> data processor.storage: 電話ログ {
style.text-transform: lowercase
}
}
user: ユーザー {
shape: person
width: 130
style.text-transform: capitalize
}
other-user: {
shape: person
style.text-transform: uppercase
}
user -> network.cell tower: 電話をかける
@ -202,7 +225,9 @@ user -> network.online portal.ui: アクセス {
style.stroke-dash: 3
}
api server: API サーバー
api server: API サーバー {
style.text-transform: lowercase
}
api server -> network.online portal.ui: 画面
api server -> logs: 持続する
logs: ログ { shape: page; style.multiple: true }

2
go.mod generated
View file

@ -22,6 +22,7 @@ require (
go.uber.org/multierr v1.9.0
golang.org/x/image v0.3.0
golang.org/x/net v0.8.0
golang.org/x/text v0.8.0
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
gonum.org/v1/plot v0.12.0
nhooyr.io/websocket v1.8.7
@ -53,7 +54,6 @@ require (
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect