1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-11 08:10:56 +00:00

Compare commits

...

11 Commits

Author SHA1 Message Date
PlantUML
3adf9c93c7
Merge pull request #1736 from travkin79/patch/1735
Fix #1735 - Fix hiding some of multiple stereotypes in clusters (rectangles, packages, etc.)
2024-04-11 22:43:19 +02:00
Dietrich Travkin
46ac4a391f Fix #1735 - Only hide the stereotype text block if it does not contain visible stereotypes 2024-04-11 17:21:35 +02:00
PlantUML
9f53546ff6
Merge pull request #1732 from The-Lum/PatchBranch
Improve `Chen diagram` management & Rename `%splitstrregex` to `%splitstr_regex`
2024-04-10 17:51:46 +02:00
The-Lum
6802c2b578 fix: rename %splitstrregex builtin function to %splitstr_regex
According to:
- https://forum.plantuml.net/18827/%25splitstr-please-add-regex-support-as-second-argument?show=18838#c18838
2024-04-10 13:25:15 +00:00
The-Lum
52fdd3bbe4 feat: Improve Chen diagram management
According to `Chen` diagram and new PlantUML Keywords from:
- #1718

Add `Chen` diagram on:
- Syntax _(improve Language Descriptor (to follow plantuml/backlog#4))_
- Sub-diagram
- Readme

_(Similar to #1669)_
_[FYI @Benjamin-Davies]_
2024-04-10 13:15:06 +00:00
PlantUML
f862254e22
Merge pull request #1731 from The-Lum/Random
feat: add `%splitstrregex` builtin function
2024-04-09 17:11:29 +02:00
PlantUML
64f3a8fc0e
Merge pull request #1730 from rubikscuber/fix-#1713
fix #1713
2024-04-09 16:51:07 +02:00
The-Lum
f3ee15f97b feat: add %splitstrregex builtin function
From this request:
- https://forum.plantuml.net/18827/%25splitstr-please-add-regex-support-as-second-argument

Ack. & Ref.:
- https://forum.plantuml.net/15374/delimited-string-split-into-an-array
- https://forum.plantuml.net/18827/%25splitstr-please-add-regex-support-as-second-argument
- https://www.javacodeexamples.com/java-stringtokenizer-using-regex-pattern/3570
2024-04-09 14:04:18 +00:00
PlantUML
e982bb326d
Merge pull request #1727 from theavege/fix/sunlust
fix json and yaml
2024-04-09 14:18:17 +02:00
rubikscuber
7c9866ac69
fix #1713 2024-04-09 14:12:21 +02:00
Artem V. Ageev
d50aa2e289 fix json and yaml 2024-04-08 15:27:16 +03:00
11 changed files with 270 additions and 93 deletions

View File

@ -60,7 +60,9 @@ PlantUML is a component that allows you to create various UML diagrams through s
- [MindMap diagram](http://plantuml.com/mindmap-diagram) - [MindMap diagram](http://plantuml.com/mindmap-diagram)
- [WBS (Work Breakdown Structure)](http://plantuml.com/wbs-diagram) - [WBS (Work Breakdown Structure)](http://plantuml.com/wbs-diagram)
- [Mathematical Notations (AsciiMath, JLaTeXMath)](http://plantuml.com/ascii-math) - [Mathematical Notations (AsciiMath, JLaTeXMath)](http://plantuml.com/ascii-math)
- [IE/ER (Information Engineering/Entity Relationship)](http://plantuml.com/ie-diagram) - Entity Relationship (ER) diagram
- [Information Engineering (IE) diagram](http://plantuml.com/ie-diagram)
- [Entity Relationship (ER) diagram (Chen's notation)](http://alphadoc.plantuml.com/doc/markdown/en/er-diagram)
### 📣 Additional Features ### 📣 Additional Features

View File

@ -122,6 +122,9 @@ public class EmbeddedDiagram extends AbstractTextBlock implements Line, Atom {
if (s.equals(EMBEDDED_START + "chronology")) if (s.equals(EMBEDDED_START + "chronology"))
return "chronology"; return "chronology";
if (s.equals(EMBEDDED_START + "chen"))
return "chen";
return null; return null;
} }

View File

@ -160,8 +160,8 @@ public final class ClusterHeader {
if (stereos == null) if (stereos == null)
return TextBlockUtils.empty(0, 0); return TextBlockUtils.empty(0, 0);
final boolean show = portionShower.showPortion(EntityPortion.STEREOTYPE, g); final List<String> visibleStereotypes = portionShower.getVisibleStereotypeLabels(g);
if (show == false) if (visibleStereotypes == null || visibleStereotypes.isEmpty())
return TextBlockUtils.empty(0, 0); return TextBlockUtils.empty(0, 0);
final Style style = Cluster final Style style = Cluster
@ -169,7 +169,7 @@ public final class ClusterHeader {
.forStereotypeItself(g.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder()); .forStereotypeItself(g.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder());
final FontConfiguration fontConfiguration = style.getFontConfiguration(skinParam.getIHtmlColorSet()); final FontConfiguration fontConfiguration = style.getFontConfiguration(skinParam.getIHtmlColorSet());
return Display.create(stereos).create(fontConfiguration, HorizontalAlignment.CENTER, skinParam); return Display.create(visibleStereotypes).create(fontConfiguration, HorizontalAlignment.CENTER, skinParam);
} }

View File

@ -95,6 +95,7 @@ public class LanguageDescriptor {
type.add("json"); type.add("json");
type.add("action"); type.add("action");
type.add("process"); type.add("process");
type.add("relationship");
keyword.add("@startwire"); keyword.add("@startwire");
keyword.add("@startbpm"); keyword.add("@startbpm");
@ -124,6 +125,7 @@ public class LanguageDescriptor {
keyword.add("@startregex"); keyword.add("@startregex");
keyword.add("@startfiles"); keyword.add("@startfiles");
keyword.add("@startchronology"); keyword.add("@startchronology");
keyword.add("@startchen");
keyword.add("@endwire"); keyword.add("@endwire");
keyword.add("@endbpm"); keyword.add("@endbpm");
keyword.add("@enduml"); keyword.add("@enduml");
@ -152,6 +154,7 @@ public class LanguageDescriptor {
keyword.add("@endregex"); keyword.add("@endregex");
keyword.add("@endfiles"); keyword.add("@endfiles");
keyword.add("@endchronology"); keyword.add("@endchronology");
keyword.add("@endchen");
keyword.add("as"); keyword.add("as");
keyword.add("also"); keyword.add("also");
keyword.add("autonumber"); keyword.add("autonumber");

View File

@ -131,6 +131,7 @@ import net.sourceforge.plantuml.tim.stdlib.ReverseHsluvColor;
import net.sourceforge.plantuml.tim.stdlib.SetVariableValue; import net.sourceforge.plantuml.tim.stdlib.SetVariableValue;
import net.sourceforge.plantuml.tim.stdlib.Size; import net.sourceforge.plantuml.tim.stdlib.Size;
import net.sourceforge.plantuml.tim.stdlib.SplitStr; import net.sourceforge.plantuml.tim.stdlib.SplitStr;
import net.sourceforge.plantuml.tim.stdlib.SplitStrRegex;
import net.sourceforge.plantuml.tim.stdlib.StringFunction; import net.sourceforge.plantuml.tim.stdlib.StringFunction;
import net.sourceforge.plantuml.tim.stdlib.Strlen; import net.sourceforge.plantuml.tim.stdlib.Strlen;
import net.sourceforge.plantuml.tim.stdlib.Strpos; import net.sourceforge.plantuml.tim.stdlib.Strpos;
@ -214,6 +215,7 @@ public class TContext {
functionsSet.addFunction(new RandomFunction()); functionsSet.addFunction(new RandomFunction());
functionsSet.addFunction(new GetAllTheme()); functionsSet.addFunction(new GetAllTheme());
functionsSet.addFunction(new GetAllStdlib()); functionsSet.addFunction(new GetAllStdlib());
functionsSet.addFunction(new SplitStrRegex());
// %standard_exists_function // %standard_exists_function
// %str_replace // %str_replace
// !exit // !exit

View File

@ -0,0 +1,74 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.tim.stdlib;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.plantuml.json.JsonArray;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.tim.EaterException;
import net.sourceforge.plantuml.tim.TContext;
import net.sourceforge.plantuml.tim.TFunctionSignature;
import net.sourceforge.plantuml.tim.TMemory;
import net.sourceforge.plantuml.tim.expression.TValue;
public class SplitStrRegex extends SimpleReturnFunction {
public TFunctionSignature getSignature() {
return new TFunctionSignature("%splitstr_regex", 2);
}
@Override
public boolean canCover(int nbArg, Set<String> namedArgument) {
return nbArg == 2;
}
@Override
public TValue executeReturnFunction(TContext context, TMemory memory, StringLocated location, List<TValue> values,
Map<String, TValue> named) throws EaterException {
final JsonArray result = new JsonArray();
final String str = values.get(0).toString();
final String separator = values.get(1).toString();
final String[] parts = str.split(separator);
for(String part : parts)
result.add(part);
return TValue.fromJson(result);
}
}

View File

@ -16,11 +16,11 @@
const N1 = res[1]; const N1 = res[1];
const N2 = res[2]; const N2 = res[2];
if (N1==nodeName) { if (N1==nodeName) {
const N2selector = `[id^=elem_${N2}]`; const N2selector = `[id=elem_${N2}]`;
nodes.add(topG.findOne(N2selector)); nodes.add(topG.findOne(N2selector));
edges.add(link); edges.add(link);
} else if (N2==nodeName) { } else if (N2==nodeName) {
const N1selector = `[id^=elem_${N1}]`; const N1selector = `[id=elem_${N1}]`;
nodes.add(topG.findOne(N1selector)); nodes.add(topG.findOne(N1selector));
edges.add(link); edges.add(link);
} }

View File

@ -2,6 +2,7 @@ package net.sourceforge.plantuml.tim;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -33,6 +34,13 @@ public class TimTestUtils {
assertEquals(expected, tValue.toString()); assertEquals(expected, tValue.toString());
} }
// Tfunc: (String, String) -> (String)
public static void assertTimExpectedOutputFromInput(TFunction func, String input1, String input2, String expected) throws EaterException {
final List<TValue> values = Arrays.asList(TValue.fromString(input1), TValue.fromString(input2));
final TValue tValue = func.executeReturnFunction(null, null, null, values, null);
assertEquals(expected, tValue.toString());
}
// Tfunc: (JsonValue) -> (String) // Tfunc: (JsonValue) -> (String)
public static void assertTimExpectedOutputFromInput(TFunction func, JsonValue input, String expected) throws EaterException { public static void assertTimExpectedOutputFromInput(TFunction func, JsonValue input, String expected) throws EaterException {
List<TValue> values = Collections.singletonList(TValue.fromJson(input)); List<TValue> values = Collections.singletonList(TValue.fromJson(input));

View File

@ -0,0 +1,34 @@
package net.sourceforge.plantuml.tim.stdlib;
import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.IndicativeSentencesGeneration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import net.sourceforge.plantuml.json.JsonValue;
import net.sourceforge.plantuml.tim.EaterException;
import net.sourceforge.plantuml.tim.TFunction;
/**
* Tests the builtin function.
*/
@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class)
class SplitStrRegexTest {
TFunction cut = new SplitStrRegex();
final String cutName = "SplitStrRegex";
@ParameterizedTest(name = "[{index}] " + cutName + "(''{0}'', ''{1}'') = {2}")
@CsvSource(nullValues = "null", value = {
" abc~def~ghi, ~, '[\"abc\",\"def\",\"ghi\"]' ",
" foozbar, z, '[\"foo\",\"bar\"]' ",
" FooBar, (?=[A-Z]), '[\"Foo\",\"Bar\"]' ",
" SomeDumbExample, (?=[A-Z]), '[\"Some\",\"Dumb\",\"Example\"]' ",
})
void Test_with_String(String input, String regex, String expected) throws EaterException {
assertTimExpectedOutputFromInput(cut, input, regex, expected);
}
}

View File

@ -0,0 +1,34 @@
package net.sourceforge.plantuml.tim.stdlib;
import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.IndicativeSentencesGeneration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import net.sourceforge.plantuml.json.JsonValue;
import net.sourceforge.plantuml.tim.EaterException;
import net.sourceforge.plantuml.tim.TFunction;
/**
* Tests the builtin function.
*/
@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class)
class SplitStrTest {
TFunction cut = new SplitStr();
final String cutName = "SplitStr";
@ParameterizedTest(name = "[{index}] " + cutName + "(''{0}'', ''{1}'') = {2}")
@CsvSource(nullValues = "null", value = {
" abc~def~ghi, ~, '[\"abc\",\"def\",\"ghi\"]' ",
" foozbar, z, '[\"foo\",\"bar\"]' ",
" FooBar, (?=[A-Z]), '[\"FooBar\"]' ",
" SomeDumbExample, (?=[A-Z]), '[\"SomeDumbExample\"]' ",
})
void Test_with_String(String input, String regex, String expected) throws EaterException {
assertTimExpectedOutputFromInput(cut, input, regex, expected);
}
}

View File

@ -1,12 +1,9 @@
'' NAME = Sunlust '' NAME = "Sunlust"
'' DESCRIPTION = sunlust theme based off of the [solarized theme](https://ethanschoonover.com/solarized) '' DESCRIPTION = "Sunlust theme based off of the [solarized theme](https://ethanschoonover.com/solarized)"
'' AUTHOR = Artem V. Ageev '' AUTHORS = ["Artem V. Ageev"]
'' LICENCE = GPL 3+ '' LICENCE = "GPL 3+"
!$THEME = 'sunlust' !$THEME = 'sunlust'
!if %not(%variable_exists("$BGCOLOR"))
!$BGCOLOR = '#fdf6e3'
!endif
scale max 2000 * 2000 scale max 2000 * 2000
!$colors = { !$colors = {
"font" : "#657b83", "font" : "#657b83",
@ -27,33 +24,71 @@ scale max 2000 * 2000
!$shapes = { !$shapes = {
"TECHNOLOGY" : { "TECHNOLOGY" : {
"color" : "#859900", "color" : "#859900",
"shapes" : [ "Node", "File"] "shapes" : [
"Node",
"File",
"Artifact",
"Circle"
]
}, },
"APPLICATION" : { "APPLICATION" : {
"color" : "#268bd2", "color" : "#268bd2",
"shapes" : [ "Participant", "Rectangle", "Component" ] "shapes" : [
"Participant",
"Rectangle",
"Component",
"Hexagon",
"Agent"
]
}, },
"BUSINESS" : { "BUSINESS" : {
"color" : "#b58900", "color" : "#b58900",
"shapes" : [ "Actor", "Note", "Hexagon", "Boundary", "Control", "Entity" ] "shapes" : [
"Actor",
"Note",
"Boundary",
"Control",
"Entity",
"Person"
]
}, },
"IMPLEMENTATION" : { "IMPLEMENTATION" : {
"color" : "#dc322f", "color" : "#dc322f",
"shapes" : [ "Class", "Map", "Json" ] "shapes" : [
"Class",
"Map",
"Json",
"Package",
"Frame",
"Interface"
]
}, },
"MOTIVATION" : { "MOTIVATION" : {
"color" : "#6c71c4", "color" : "#6c71c4",
"shapes" : [ "Cloud", "Frame", "Collections", "Database", "Queue" ] "shapes" : [
"Cloud",
"Collections",
"Database",
"Queue",
"Process",
"Stack",
"Storage"
]
}, },
"STRATEGY" : { "STRATEGY" : {
"color" : "#STRATEGY", "color" : "#cb4b16",
"shapes" : [ "Partition", "Folder", "Card" ] "shapes" : [
"Action",
"Partition",
"Folder",
"Usecase",
"Card"
]
} }
} }
!$thickness = 2 !$thickness = 2
<style> <style>
!foreach $lib in %splitstr('root.wbsDiagram.mindmapDiagram.ganttDiagram.saltDiagram', '.') nwdiagDiagram, wbsDiagram, mindmapDiagram, ganttDiagram, saltDiagram, jsonDiagram, yamlDiagram {
$lib {
BackGroundColor $colors.bg BackGroundColor $colors.bg
arrow { arrow {
LineColor $colors.font LineColor $colors.font
@ -72,62 +107,44 @@ scale max 2000 * 2000
BackGroundColor $colors.red_bg BackGroundColor $colors.red_bg
} }
} }
!endfor
</style> </style>
skinparam {
noteTextAlignment left skinparam noteTextAlignment left
actorStyle awesome skinparam actorStyle awesome
Dpi 100 skinparam Dpi 100
Shadowing false skinparam Shadowing false
BackgroundColor $colors.bg skinparam BackgroundColor $colors.bg
WrapWidth 200 skinparam WrapWidth 200
RoundCorner 15 skinparam RoundCorner 15
Swimlane { skinparam SwimlaneBorderColor $colors.font
BorderColor $colors.font skinparam SwimlaneThickness $thickness
Thickness $thickness skinparam SwimlaneWrapTitleWidth 150
WrapTitleWidth 150 skinparam ArrowColor $colors.font
} skinparam ArrowThickness $thickness
Arrow { skinparam DefaultTextAlignment center
Color $colors.font skinparam DefaultFontName Dejavu Serif
Thickness $thickness skinparam LegendFontName VL Gothic
} skinparam LegendBorderColor transparent
Default { skinparam LegendBackgroundColor transparent
TextAlignment center skinparam SequenceMessageAlign direction
FontName Dejavu Serif skinparam SequenceArrowThickness $thickness
} skinparam SequenceLifeLineBorderColor $colors.yellow
Legend { skinparam SequenceBoxBorderThickness $thickness
FontName VL Gothic
BorderColor transparent
BackgroundColor transparent
}
Sequence {
MessageAlign direction
ArrowThickness $thickness
LifeLineBorderColor $colors.yellow
BoxBorderThickness $thickness
}
!foreach $shape in %splitstr('Activity.State', '.') !foreach $shape in %splitstr('Activity.State', '.')
$shape { skinparam $shape {
BackgroundColor transparent BackgroundColor transparent
Border { BorderColor $colors.violet
Color $colors.violet BorderThickness $thickness
Thickness $thickness DiamondBorderColor $colors.red
} DiamondBackgroundColor transparent
Diamond {
BorderColor $colors.red
BackgroundColor transparent
}
} }
!endfor !endfor
!foreach $key in %get_json_keys($shapes) !foreach $key in %get_json_keys($shapes)
!foreach $shape in $shapes[$key].shapes !foreach $shape in $shapes[$key].shapes
$shape { skinparam $shape {
BackgroundColor #$key BackgroundColor #$key
Border { BorderColor $shapes[$key].color
Color $shapes[$key].color BorderThickness $thickness
Thickness $thickness
}
} }
!endfor !endfor
!endfor !endfor
}