diff --git a/skin/plantuml.skin b/skin/plantuml.skin index e4ba76e7c..ba90f4322 100644 --- a/skin/plantuml.skin +++ b/skin/plantuml.skin @@ -394,7 +394,7 @@ yamlDiagram,jsonDiagram { LineColor black arrow { LineThickness 1 - LineStyle 3;3 + LineStyle 3-3 } node { LineThickness 1.5 @@ -462,7 +462,7 @@ timingDiagram { highlight { BackgroundColor #e LineThickness 2 - LineStyle 4;4 + LineStyle 4-4 } } diff --git a/skin/rose.skin b/skin/rose.skin index 0ec9589b7..420e84933 100644 --- a/skin/rose.skin +++ b/skin/rose.skin @@ -460,7 +460,7 @@ yamlDiagram,jsonDiagram { LineColor black arrow { LineThickness 1 - LineStyle 3;3 + LineStyle 3-3 } node { LineThickness 1.5 @@ -517,7 +517,7 @@ timingDiagram { highlight { BackgroundColor #e LineThickness 2 - LineStyle 4;4 + LineStyle 4-4 } } diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index 83b80dad4..ed7bd915e 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -114,8 +114,6 @@ public interface ISkinParam extends ISkinSimple { public LineBreakStrategy maxMessageSize(); - public LineBreakStrategy wrapWidth(); - public LineBreakStrategy swimlaneWrapTitleWidth(); public boolean strictUmlStyle(); diff --git a/src/net/sourceforge/plantuml/ISkinSimple.java b/src/net/sourceforge/plantuml/ISkinSimple.java index da71fd63b..acdbef138 100644 --- a/src/net/sourceforge/plantuml/ISkinSimple.java +++ b/src/net/sourceforge/plantuml/ISkinSimple.java @@ -59,8 +59,6 @@ public interface ISkinSimple extends SpriteContainer { public int getDpi(); - public LineBreakStrategy wrapWidth(); - public void copyAllFrom(Map other); public SheetBuilder sheet(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 430308e81..817680ef5 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -81,6 +81,7 @@ import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.StyleLoader; import net.sourceforge.plantuml.style.parser.StyleParser; +import net.sourceforge.plantuml.style.parser.StyleParsingException; import net.sourceforge.plantuml.svek.ConditionEndStyle; import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.svek.PackageStyle; @@ -111,6 +112,8 @@ public class SkinParam implements ISkinParam { if (styleBuilder == null) try { this.styleBuilder = getCurrentStyleBuilderInternal(); + } catch (StyleParsingException e) { + Logme.error(e); } catch (IOException e) { Logme.error(e); } @@ -133,7 +136,7 @@ public class SkinParam implements ISkinParam { this.skin = newSkin; } - public StyleBuilder getCurrentStyleBuilderInternal() throws IOException { + public StyleBuilder getCurrentStyleBuilderInternal() throws IOException, StyleParsingException { final StyleLoader tmp = new StyleLoader(this); StyleBuilder result = tmp.loadSkin(this.getDefaultSkin()); if (result == null) @@ -183,6 +186,8 @@ public class SkinParam implements ISkinParam { for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder)) this.muteStyle(modifiedStyle); + } catch (StyleParsingException e) { + Logme.error(e); } catch (IOException e) { Logme.error(e); } @@ -894,12 +899,6 @@ public class SkinParam implements ISkinParam { return new LineBreakStrategy(value); } - @Override - public LineBreakStrategy wrapWidth() { - final String value = getValue("wrapwidth"); - return new LineBreakStrategy(value); - } - @Override public LineBreakStrategy swimlaneWrapTitleWidth() { final String value = getValue("swimlanewraptitlewidth"); diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java index c9ae054b6..8dc9c281e 100644 --- a/src/net/sourceforge/plantuml/SkinParamDelegator.java +++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java @@ -187,11 +187,6 @@ public class SkinParamDelegator implements ISkinParam { return skinParam.maxMessageSize(); } - @Override - public LineBreakStrategy wrapWidth() { - return skinParam.wrapWidth(); - } - @Override public boolean strictUmlStyle() { return skinParam.strictUmlStyle(); diff --git a/src/net/sourceforge/plantuml/SpriteContainerEmpty.java b/src/net/sourceforge/plantuml/SpriteContainerEmpty.java index 0df0c99f7..644e494ec 100644 --- a/src/net/sourceforge/plantuml/SpriteContainerEmpty.java +++ b/src/net/sourceforge/plantuml/SpriteContainerEmpty.java @@ -90,11 +90,6 @@ public class SpriteContainerEmpty implements SpriteContainer, ISkinSimple { return 96; } - @Override - public LineBreakStrategy wrapWidth() { - return LineBreakStrategy.NONE; - } - @Override public void copyAllFrom(Map other) { throw new UnsupportedOperationException(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java index 4ecc00caf..1fbc9a641 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandCase; import net.sourceforge.plantuml.activitydiagram3.command.CommandCircleSpot3; import net.sourceforge.plantuml.activitydiagram3.command.CommandElse3; import net.sourceforge.plantuml.activitydiagram3.command.CommandElseIf2; +import net.sourceforge.plantuml.activitydiagram3.command.CommandElseIf3; import net.sourceforge.plantuml.activitydiagram3.command.CommandElseLegacy1; import net.sourceforge.plantuml.activitydiagram3.command.CommandEnd3; import net.sourceforge.plantuml.activitydiagram3.command.CommandEndPartition3; @@ -111,6 +112,7 @@ public class ActivityDiagramFactory3 extends PSystemCommandFactory { cmds.add(new CommandIf2()); cmds.add(CommandDecoratorMultine.create(new CommandIf2(), 50)); cmds.add(new CommandIfLegacy1()); + cmds.add(new CommandElseIf3()); cmds.add(new CommandElseIf2()); cmds.add(new CommandElse3()); cmds.add(CommandDecoratorMultine.create(new CommandElse3(), 50)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf3.java new file mode 100644 index 000000000..359b9c9a6 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf3.java @@ -0,0 +1,121 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://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.activitydiagram3.command; + +import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; +import net.sourceforge.plantuml.activitydiagram3.LinkRendering; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; +import net.sourceforge.plantuml.graphic.color.ColorParser; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; +import net.sourceforge.plantuml.utils.LineLocation; + +public class CommandElseIf3 extends SingleLineCommand2 { + + public CommandElseIf3() { + super(getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandElseIf3.class.getName(), RegexLeaf.start(), // + ColorParser.exp4(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexOptional(new RegexConcat( // + new RegexLeaf("\\("), // + new RegexOptional(new RegexOr(// + new RegexLeaf("->"), // + new RegexLeaf("INCOMING_COLOR", CommandLinkElement.STYLE_COLORS_MULTIPLES))), // + new RegexLeaf("INCOMING", "(.*?)"), // + new RegexLeaf("\\)"))), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("else"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("if"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("\\("), // + new RegexLeaf("TEST", "(.*?)"), // + new RegexLeaf("\\)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("(is|equals?)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("\\("), // + new RegexLeaf("WHEN", "(.+?)"), // + new RegexLeaf("\\)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexOptional( // + new RegexConcat( // + new RegexLeaf("then"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexOptional(new RegexConcat( // + new RegexLeaf("\\("), // + new RegexOptional(new RegexOr(// + new RegexLeaf("->"), // + new RegexLeaf("WHEN_COLOR", + CommandLinkElement.STYLE_COLORS_MULTIPLES))), // + new RegexLeaf("\\)"))) // + )), // + new RegexLeaf(";?"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) + throws NoSuchColorException { + final String s = arg.get("COLOR", 0); + final HColor color = s == null ? null + : diagram.getSkinParam().getIHtmlColorSet().getColor(s); + + String test = arg.get("TEST", 0); + if (test.length() == 0) { + test = null; + } + + final LinkRendering incoming = CommandBackward3.getBackRendering(diagram, arg, "INCOMING"); + final LinkRendering when = CommandBackward3.getBackRendering(diagram, arg, "WHEN"); + + return diagram.elseIf(incoming, Display.getWithNewlines(test), when, color); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java index b42cd4648..d52ca3621 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java @@ -266,7 +266,7 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock, Styleable private LineBreakStrategy getWrap() { LineBreakStrategy wrap = skinParam.swimlaneWrapTitleWidth(); if (wrap == LineBreakStrategy.NONE) - wrap = skinParam.wrapWidth(); + wrap = style.wrapWidth(); return wrap; } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorAssembly.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorAssembly.java index db7813ada..0d84fc5a4 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorAssembly.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorAssembly.java @@ -97,6 +97,4 @@ public class FtileFactoryDelegatorAssembly extends FtileFactoryDelegator { return result; } - private final Rose rose = new Rose(); - } diff --git a/src/net/sourceforge/plantuml/baraye/CucaDiagram.java b/src/net/sourceforge/plantuml/baraye/CucaDiagram.java index 754c85213..aae05019b 100644 --- a/src/net/sourceforge/plantuml/baraye/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/baraye/CucaDiagram.java @@ -105,8 +105,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, public Quark currentQuark() { throw new UnsupportedOperationException(); } - - public /*protected*/ Plasma getPlasma() { + + public /* protected */ Plasma getPlasma() { throw new UnsupportedOperationException(); } @@ -305,13 +305,27 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, return Collections.unmodifiableCollection(result); } - final public void gotoGroup(Ident ident, Code code, Display display, GroupType type, IGroup parent, - NamespaceStrategy strategy) { - if (this.V1972()) { - gotoGroupInternalWithNamespace(ident, code, display, code, type, parent); - return; + private NamespaceStrategy lastNamespaceStrategy; + + final public CommandExecutionResult gotoGroup(Ident ident, Code code, Display display, GroupType type, + IGroup parent, NamespaceStrategy strategy) { + if (type == GroupType.TOGETHER) { + IGroup result = entityFactory.createGroup(ident, code, display, null, type, parent, getHides(), + getNamespaceSeparator()); + entityFactory.addGroup(result); + currentGroup = result; + return CommandExecutionResult.ok(); } + if (this.V1972()) { + gotoGroupInternalWithNamespace(ident, code, display, code, type, parent); + return CommandExecutionResult.ok(); + } + + if (this.lastNamespaceStrategy != null && strategy != this.lastNamespaceStrategy) + return CommandExecutionResult.error("Cannot mix packages and namespaces"); + this.lastNamespaceStrategy = strategy; + if (strategy == NamespaceStrategy.MULTIPLE) { if (getNamespaceSeparator() != null) code = getFullyQualifiedCode1972(code); @@ -324,6 +338,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, } else { throw new IllegalArgumentException(); } + return CommandExecutionResult.ok(); } protected final String getNamespace1972(Code fullyCode, String separator) { @@ -373,6 +388,12 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, } public void endGroup() { + + if (currentGroup.getGroupType() == GroupType.TOGETHER) { + currentGroup = currentGroup.getParentContainer(); + return; + } + if (stacks2.size() > 0) { // Thread.dumpStack(); stacks2.remove(stacks2.size() - 1); @@ -672,6 +693,9 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, } public boolean isAutarkic(IGroup g) { + if (g.getGroupType() == GroupType.TOGETHER) + return false; + if (g.getGroupType() == GroupType.PACKAGE) return false; diff --git a/src/net/sourceforge/plantuml/baraye/EntityFactory.java b/src/net/sourceforge/plantuml/baraye/EntityFactory.java index 72ec0772d..f573a7adf 100644 --- a/src/net/sourceforge/plantuml/baraye/EntityFactory.java +++ b/src/net/sourceforge/plantuml/baraye/EntityFactory.java @@ -131,7 +131,8 @@ public final class EntityFactory implements IEntityFactory { final Collection children = parent.getChildren(); if (leafs == 0 && children.size() == 1) { final IGroup g = children.iterator().next(); - if (g.getLeafsDirect().size() == 0 && g.getChildren().size() == 0 && g.getGroupType() == GroupType.PACKAGE) + if (g.getLeafsDirect().size() == 0 && g.getChildren().size() == 0 + && (g.getGroupType() == GroupType.PACKAGE || g.getGroupType() == GroupType.TOGETHER)) return null; for (Link link : this.getLinks()) @@ -192,20 +193,24 @@ public final class EntityFactory implements IEntityFactory { return result; } - private IEntity isNoteWithSingleLinkAttachedTo(ILeaf leaf) { - if (leaf.getLeafType() != LeafType.NOTE) + private IEntity isNoteWithSingleLinkAttachedTo(ILeaf note) { + if (note.getLeafType() != LeafType.NOTE) return null; - IEntity result = null; + assert note.getLeafType() == LeafType.NOTE; + IEntity other = null; for (Link link : this.getLinks()) { if (link.getType().isInvisible()) continue; - if (link.contains(leaf)) { - if (result != null) - return result; - result = link.getOther(leaf); - } + if (link.contains(note) == false) + continue; + if (other != null) + return null; + other = link.getOther(note); + if (other.getLeafType() == LeafType.NOTE) + return null; + } - return result; + return other; } diff --git a/src/net/sourceforge/plantuml/baraye/EntityImp.java b/src/net/sourceforge/plantuml/baraye/EntityImp.java index 62de8c18f..8f8b97ea3 100644 --- a/src/net/sourceforge/plantuml/baraye/EntityImp.java +++ b/src/net/sourceforge/plantuml/baraye/EntityImp.java @@ -171,8 +171,8 @@ final public class EntityImp implements ILeaf, IGroup { this.rawLayout = rawLayout; } - public EntityImp(Ident ident, Code code, EntityFactory entityFactory, Bodier bodier, - IGroup parentContainer, LeafType leafType, String namespaceSeparator, int rawLayout) { + public EntityImp(Ident ident, Code code, EntityFactory entityFactory, Bodier bodier, IGroup parentContainer, + LeafType leafType, String namespaceSeparator, int rawLayout) { this(Objects.requireNonNull(ident), entityFactory, code, bodier, parentContainer, namespaceSeparator, rawLayout); // System.err.println("ID for leaf=" + code + " " + ident); @@ -782,6 +782,7 @@ final public class EntityImp implements ILeaf, IGroup { public void setThisIsTogether() { this.together = true; + setUSymbol(USymbols.TOGETHER); } public String getCodeLine() { diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java index 8298f21c9..c4672cedf 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -76,6 +76,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementMultilin import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementParenthesis; import net.sourceforge.plantuml.descdiagram.command.CommandNewpage; import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; +import net.sourceforge.plantuml.descdiagram.command.CommandTogether; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; @@ -118,6 +119,7 @@ public class ClassDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandEndPackage()); cmds.add(new CommandPackageEmpty()); cmds.add(new CommandPackageWithUSymbol()); + cmds.add(new CommandTogether()); cmds.add(new CommandCreateElementFull2(Mode.NORMAL_KEYWORD)); cmds.add(new CommandCreateElementFull2(Mode.WITH_MIX_PREFIX)); diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace.java b/src/net/sourceforge/plantuml/command/CommandNamespace.java index bd66debd8..1cf2d91ad 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespace.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespace.java @@ -106,12 +106,14 @@ public class CommandNamespace extends SingleLineCommand2 { currentPackage = diagram.getCurrentGroup(); display = Display.getWithNewlines(code); } - diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); + final CommandExecutionResult status = diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, + currentPackage, NamespaceStrategy.MULTIPLE); + if (status.isOk() == false) + return status; final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); - if (stereotype != null) { + if (stereotype != null) p.setStereotype(Stereotype.build(stereotype)); - } final String urlString = arg.get("URL", 0); if (urlString != null) { @@ -121,9 +123,9 @@ public class CommandNamespace extends SingleLineCommand2 { } final String color = arg.get("COLOR", 0); - if (color != null) { + if (color != null) p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color)); - } + return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace2.java b/src/net/sourceforge/plantuml/command/CommandNamespace2.java index 7f7d8754e..5fb712651 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespace2.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespace2.java @@ -94,12 +94,14 @@ public class CommandNamespace2 extends SingleLineCommand2 { final IGroup currentPackage = diagram.getCurrentGroup(); final String disp = arg.getLazzy("DISPLAY", 0); final Display display = Display.getWithNewlines(disp); - diagram.gotoGroup(ident, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); + final CommandExecutionResult status = diagram.gotoGroup(ident, code, display, GroupType.PACKAGE, + currentPackage, NamespaceStrategy.MULTIPLE); + if (status.isOk() == false) + return status; final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); - if (stereotype != null) { + if (stereotype != null) p.setStereotype(Stereotype.build(stereotype)); - } final String urlString = arg.get("URL", 0); if (urlString != null) { @@ -109,9 +111,9 @@ public class CommandNamespace2 extends SingleLineCommand2 { } final String color = arg.get("COLOR", 0); - if (color != null) { + if (color != null) p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color)); - } + return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java b/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java index 04df5278c..a932ef841 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java @@ -88,12 +88,14 @@ public class CommandNamespaceEmpty extends SingleLineCommand2 { final Code code = diagram.V1972() ? idNewLong : diagram.buildCode(idShort); final IGroup currentPackage = diagram.getCurrentGroup(); final Display display = Display.getWithNewlines(code); - diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); + final CommandExecutionResult status = diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, + currentPackage, NamespaceStrategy.MULTIPLE); + if (status.isOk() == false) + return status; final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); - if (stereotype != null) { + if (stereotype != null) p.setStereotype(Stereotype.build(stereotype)); - } final String urlString = arg.get("URL", 0); if (urlString != null) { @@ -103,9 +105,9 @@ public class CommandNamespaceEmpty extends SingleLineCommand2 { } final String color = arg.get("COLOR", 0); - if (color != null) { + if (color != null) p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color)); - } + diagram.endGroup(); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/command/CommandPackage.java b/src/net/sourceforge/plantuml/command/CommandPackage.java index b2ad39674..6e0193645 100644 --- a/src/net/sourceforge/plantuml/command/CommandPackage.java +++ b/src/net/sourceforge/plantuml/command/CommandPackage.java @@ -128,7 +128,7 @@ public class CommandPackage extends SingleLineCommand2 { final Ident ident; final Code code; - + if (CucaDiagram.QUARK) { final Quark current = diagram.currentQuark(); code = current; @@ -140,9 +140,10 @@ public class CommandPackage extends SingleLineCommand2 { display = ident.getLast(); } final IGroup currentPackage = diagram.getCurrentGroup(); - - diagram.gotoGroup(ident, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, - NamespaceStrategy.SINGLE); + final CommandExecutionResult status = diagram.gotoGroup(ident, code, Display.getWithNewlines(display), + GroupType.PACKAGE, currentPackage, NamespaceStrategy.SINGLE); + if (status.isOk() == false) + return status; final IEntity p = diagram.getCurrentGroup(); diff --git a/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java b/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java index a33023131..988694c84 100644 --- a/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java +++ b/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java @@ -100,14 +100,15 @@ public class CommandPackageEmpty extends SingleLineCommand2 { return create7(fontConfiguration, horizontalAlignment, spriteContainer, CreoleMode.FULL); } - public TextBlock createWithNiceCreoleMode(FontConfiguration fontConfiguration, - HorizontalAlignment horizontalAlignment, ISkinSimple spriteContainer) { - return create7(fontConfiguration, horizontalAlignment, spriteContainer, defaultCreoleMode); - } - public TextBlock create7(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, ISkinSimple spriteContainer, CreoleMode creoleMode) { return create0(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode, diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupType.java b/src/net/sourceforge/plantuml/cucadiagram/GroupType.java index 98b65aeb4..193403e4c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/GroupType.java +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupType.java @@ -37,6 +37,6 @@ package net.sourceforge.plantuml.cucadiagram; public enum GroupType { - PACKAGE, STATE, CONCURRENT_STATE, INNER_ACTIVITY, CONCURRENT_ACTIVITY, DOMAIN, REQUIREMENT + PACKAGE, TOGETHER, STATE, CONCURRENT_STATE, INNER_ACTIVITY, CONCURRENT_ACTIVITY, DOMAIN, REQUIREMENT } diff --git a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java index c698ae156..368dbbd95 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java @@ -242,7 +242,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlock, config = config.underline(); TextBlock bloc = Display.getWithNewlines(s).create8(config, align, skinParam, CreoleMode.SIMPLE_LINE, - skinParam.wrapWidth()); + style.wrapWidth()); bloc = TextBlockUtils.fullInnerPosition(bloc, m.getDisplay(false)); return new TextBlockTracer(m, bloc); } @@ -251,7 +251,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlock, // return ((EmbeddedDiagram) cs).asDraw(skinParam); return Display.getWithNewlines(cs.toString()).create8(config, align, skinParam, CreoleMode.SIMPLE_LINE, - skinParam.wrapWidth()); + style.wrapWidth()); } diff --git a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java index 8009f13b4..07ef66761 100644 --- a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java +++ b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java @@ -61,6 +61,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementMultilin import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; import net.sourceforge.plantuml.descdiagram.command.CommandNewpage; import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; +import net.sourceforge.plantuml.descdiagram.command.CommandTogether; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap; @@ -83,8 +84,10 @@ public class DescriptionDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandLinkElement()); cmds.add(new CommandHideShow2()); cmds.add(new CommandRemoveRestore()); - // + cmds.add(new CommandPackageWithUSymbol()); + cmds.add(new CommandTogether()); + cmds.add(new CommandEndPackage()); final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote(); cmds.add(factoryNoteCommand.createMultiLine(false)); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java index 65bfcf105..6601c2a85 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java @@ -74,7 +74,7 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2 { + + public CommandTogether() { + super(getRegexConcat()); + } + + private static IRegex getRegexConcat() { + return RegexConcat.build(CommandTogether.class.getName(), RegexLeaf.start(), // + new RegexLeaf("together"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("\\{"), RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(AbstractEntityDiagram diagram, LineLocation location, RegexResult arg) + throws NoSuchColorException { + final String idShort = diagram.getUniqueSequence("##"); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); + + final IGroup currentPackage = diagram.getCurrentGroup(); + final CommandExecutionResult status = diagram.gotoGroup(ident, code, Display.NULL, GroupType.TOGETHER, + currentPackage, NamespaceStrategy.SINGLE); + if (status.isOk() == false) + return status; + final IEntity p = diagram.getCurrentGroup(); + p.setThisIsTogether(); + + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index 9bf278c91..20e0fcd4a 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -71,31 +71,30 @@ public class PSystemDonors extends PlainDiagram { private static final int COLS = 6; private static final int FREE_LINES = 6; - public static final String DONORS = "6miF03mSRygAr4-2sU91UhPs3uiVqvmG9uBbUK9nOX6dku3u0zmxFUutqbz4LtRlcsP4hTScvGoY-Y3e" - + "0Uzk2-r3wNzz4EOiUH7ScH9SG0g8ukWI-P5kP3jzKcL82TvyX-vlcQmzsJek5ZMV4u6h02gHaD6SOhkN" - + "YNczGYgb-FoLZz1Fu6tww3nt6aMZ_XEuUTJsKUnzpVzDdMNdeH1cwMu5Hc1KD49rth77-FyKGOKes3bK" - + "mOubntGghLeELNICUL_N0dLCkbPDauygDQjYN5MaM4Od3Oj89jJbOl8nyg9F6h_Kc_3XkYeauzu1dMrr" - + "T7tJspRFnFppHH-2ZC4t53Km0jOZQHFDpqCF6aOE66fsuSOM5OuyYOT46hIGN_vGc48loTaLSDCmgG24" - + "nJjGWIG7rQdXRCTXG8KbjcYpyAYB_S7Ik2uhfp9TQNWYiJ4nKGkeKkH_q0tTKUjuD7NtC3WYFIKQOSjH" - + "FWjifHrMzFbPIWGBWCwOnVehH3cLr7GSpzg_Soq0kwNbLGzZ2dzEe2bBA9JnYGNgLw7Rve8jUkzoi906" - + "KH-7R_g8S-MXkWX7P4fPhQENiPrhcJzqsOBrINWABEGzxakn1HniYgigDO0lj0ffgVC992tpxwN7ot_V" - + "4wufb6IlNxGHhf3qquznCaCXGFkcCHkwYGABiIfMhSKMHB17wT00hOLa4CwHTjb7_99-vIS0tbn2T9kD" - + "G3tuzvUc31svI0C9NPN62c3rQKNTDCmUmQ1KKz7rHCMNtiQFhqnhx6EbiMfPjCdpHeCnyfjqcc9ZkK95" - + "XXaMwc7DcU_KbcYNucxfWrUz9tjT1RYKUG-vSUyN6V1p3nce59pkUCz7Rbc62OjPF7EzJEcPdqnk7hhn" - + "m5qiciQCClMGPS1WVoAgzP6eRnOZl-sGpSXh9Re7iBuA90SFCoh1woScLrHpJCDeaqLqR14YsToyufHT" - + "kRPWCozFagEYHChDLWz3Gdv7-YAYLT96gSFcV9VW6PAZ82_dtR7gCN-xOUe2AbCdWKzQi6PBQD-pBf21" - + "jOkUgPR4wVy-iI3lVJampL1y9Oas7jn0CGLcXd0V65WY6SXAnKkR617ulZ_kZXxnEjJZRvzECGwIRf8O" - + "g8A4arzGJTHPHuGJwpN-_wPFIrpuywyzRPDJlJtx7e9eCuWBG9WNw8gS5q8y1RusDam1dC8I5vqaNBbi" - + "xPL0b8ADzC4kwlPbHld6JvORaPlMNZzKuKzJZ0h7_K2s2r_HtkUIAjCNqwW6-yEx3XSv6FubgWo8vB8t" - + "CoiZKIR1nN4VfxKDpLWwG0tcG9q4djtzsMAXeR7sAvGgmmcGhpSabHfbMbWTqzBO2AoK4_jxQqxA6VNP" - + "6SJF7klCULKFTPCKrrECA7o7ISXJmiJC8d4YWjtYEIb13z_i8rzK2oMnjAdDpX2iaF--7yCR2GVia0SQ" - + "zOHIdcb13jkaUziiy4U2zn0ba8N5Cjr5B9JAU215KZ2NMyOpfA-q6QVs1j0f2iR_zmQKoqmqFwBPfNTr" - + "ahd2rdRY82h3_PubjYZPQf61VLVDPUkNvRRDJMROaV-17plV_AYwVX41DKHN9NZDQUJ3ZSrgQjYY_cOE" - + "zt6PhPl9p-DIj7DK0vlqPAE6iXaev2I4I0T2XVHL-5Nz2LlEEVBfVQeK1cfu7hiDFNYk1kR8LXfU9Gse" - + "NcHnR7s_uIPF3XHEJBR-LQUnqyEO7gqmrAQRDcl8e1AvIyLNZc1sSqcLjoecbJAyy-FUKBCajFQTxUZq" - + "JcuXbzTpFBqnWqlzakWpmJa6ch9U7CY41cGHMK4ZYAwI_Q8LPyYeBAl4HwfWc3ZQ4kxGQ3DOk3lMfw5i" - + "NZ5RuziaFZ126vR-nWNSUuP4pmKD8zkS06nO52cKX6OetMCGEs57p2vkUISVW_BMtW00"; - + public static final String DONORS = "6r8F0AoFktsyGOBPua5wjfPR-fZcX3WHBCyJYiF0HZpT1SGVuDxfSR-H_YAwqhrlcZ5glPofDGbvnfSS" + + "iFHQuIQCt_d2eyvUFWIVD0A61iW0SLF_nZdioMcw8rM6bE3DT-Z-bidQawtZOb7pEH6u2g0IqPnYkvU9" + + "URr2AgNu_9MFq4yWcuBESwPH96fUuEQexQVO-vhxdpexbp1BToim0gEY4QhylkPOUxarxw9QL8c2dQ0A" + + "TepbL5gr7AgeZ2tBoCS-CD6QGpwgrAoACHUHOXYTD0mY4QZBnUXZvCMOL7wfD-73TLL8Hjq1dMqDT7tJ" + + "sZRFnFJpHH-XqWRVOAJ025YEn4sqV1v6KD5oG52pYsniKUN8apXGf48B_kKFXQcCafnT0JKLdGP067m7" + + "AeXafperd6qw3AYmn1Pj5guwrzzO6k_BybIc2mrF83Ow9bg1LOBy3xh1EsiTZqIrXq4HwIdH6BOSvNCe" + + "M-c75NrkrX910g1Jit1_-IYdahgEurdxTwu5uB2qVDV37CET4sZA4gh8-6X1nXNehBKWYzwx72oaGDZ7" + + "uPinTAuyj2p2DfvI5clxPMnxBVE7hhJ1-iGy1HR-FVPBhWKSQj9LaXR05rg5TEjyef2M-VVIuzj_tnEk" + + "AUIurotw25T8-kt7sCnO2D2-PKX3Dq4W2TobLMkn1H7g4TetG6iX6OHpf5ts4R-aZ_m4m5kM4CDX4qez" + + "-FDBKQQENAW93rsLnWfWQR6YRIfwZs1GgYdeObHnPRJnuolJEljODfOiYpvvNcem9dvDfoWsbYjKP8PX" + + "eHxHdFcsjfLs2MwNCNZLVM9b5T1QuJtanhrVP22VUyX49EyCnti-SiioJKZCufZhPKhF-cHoyz2D2yxi" + + "fYSpofH3bW6TtSberaUiiLbCVpF8PkIridWCO7mDHLlmCACOl7uqEQQQOofQcooYOeiGITRc5RkOS1P1" + + "dfOZoL5HGkKMgriX8RzjOn6HAd6Zr65pkZFm3EzHb9VppbdrcB_TIie2AbERm2KjIAkbOj-pBf2XUoSz" + + "Kos9C_vzOi6sz-M1mQ7qYecM7jm0c4AIBZ8F128HEWgbz58cXWM-xhUxrUDp7TBnjq-d68T83qa2L073" + + "sLvGZTJPHeIDzHh_VzEd9Ixy-TUwRPDJlRtttONGE4WMW0WlDAIS4q8y1JutDam6dCAIB3f9k7BMqek1" + + "o8ADZC4kwcoPqNRZ9ykDo4rlBn-gyAUhN5JOwGTqNBXIx7qkgJ9zCOEAsRxnZSL53W7_4bL6PNBlAgDP" + + "OIJYA6HnxCVfRKFJ5pf8mHgeJU3OtUyj5XgQQxyYgJGSW7oo8QdKhD2YQarBOoEmKaxixwquAMVMPsUY" + + "7zCwSrxLGzqaPzTJZ2Xy-oaqzmWJqqNSX8LmJyv934Rune9yKIsMnDAo3ZjDi8B_-tuCRoHiieCF5Ee9" + + "fJpJWXnXa-nzgoZ-8DvTn40M5ijq9x5Ool58YgHmhcoPd25zfKyufMyGWw9m_7ylGRZCHFCLaYwzgvFC" + + "vRTMamoYEDJF9Ab5obQB3EoRIovRl2AtRMtIOTl-1txYVFaZwkAR220GpONWDQUX3pVMgwbX2_ARETp7" + + "PRPk9Z-FIz7EKGbirYSRDS1cgE991647e49u3VrL_GbRpcNus_DKAepKyDnH3JruhWQMaQqql4WQrBp8" + + "OjhwVifDdXn8d00TKAawZPqUneneXKCjlscp98DAuauL_ti6qjqbLTwgc3JAaAXwWysIs3hlpD3fdDmg" + + "N5xFyVJ632dr2-eBWZs6kbpF3NW20meXhW05oLNpljMACsHKbbNZmoeKHWws5JKqsWmMsHtZqr0shvYj" + + "yUpO5i08L0pzWmjxZuP6JgXesUQ4CXiH1ObIQ0ieiySejc6VaYvkEJMTj_PENUY7pPDDDVeMbUB0EZoZ" + "yWe1"; /* * Special thanks to our sponsors and donors: * diff --git a/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java b/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java index f80334559..bcab0e7ce 100644 --- a/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java +++ b/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java @@ -99,7 +99,7 @@ public class EbnfExpression implements TextBlockable { tokens.add(new Token(Symbol.REPETITION_OPEN, null)); } else if (ch == '}' && it.peek(1) == '-') { tokens.add(new Token(Symbol.REPETITION_MINUS_CLOSE, null)); - it.next(); + it.jump(); } else if (ch == '}') { tokens.add(new Token(Symbol.REPETITION_CLOSE, null)); } else if (ch == ';' || ch == 0) { @@ -118,7 +118,7 @@ public class EbnfExpression implements TextBlockable { tokens.clear(); return; } - it.next(); + it.jump(); continue; } } @@ -213,14 +213,14 @@ public class EbnfExpression implements TextBlockable { private String readString(CharInspector it) { final char separator = it.peek(0); - it.next(); + it.jump(); final StringBuilder sb = new StringBuilder(); while (true) { final char ch = it.peek(0); if (ch == separator) return sb.toString(); sb.append(ch); - it.next(); + it.jump(); } } @@ -231,25 +231,25 @@ public class EbnfExpression implements TextBlockable { if (isLetterOrDigit(ch) == false) return sb.toString(); sb.append(ch); - it.next(); + it.jump(); } } private String readComment(CharInspector it) { final StringBuilder sb = new StringBuilder(); - it.next(); - it.next(); + it.jump(); + it.jump(); while (true) { final char ch = it.peek(0); if (ch == '\0') return sb.toString(); if (ch == '*' && it.peek(1) == ')') { - it.next(); - it.next(); + it.jump(); + it.jump(); return sb.toString(); } sb.append(ch); - it.next(); + it.jump(); } } diff --git a/src/net/sourceforge/plantuml/eggs/EggUtils.java b/src/net/sourceforge/plantuml/eggs/EggUtils.java index 17af85f52..8e23364b0 100644 --- a/src/net/sourceforge/plantuml/eggs/EggUtils.java +++ b/src/net/sourceforge/plantuml/eggs/EggUtils.java @@ -45,9 +45,9 @@ public class EggUtils { final StringBuilder sb = new StringBuilder(); for (byte b : data) { final String hex = Integer.toHexString(b & 0xFF); - if (hex.length() == 1) { + if (hex.length() == 1) sb.append('0'); - } + sb.append(hex); } return sb.toString(); @@ -55,9 +55,9 @@ public class EggUtils { public static byte[] toByteArrays(String s) { final byte[] result = new byte[s.length() / 2]; - for (int i = 0; i < result.length; i++) { + for (int i = 0; i < result.length; i++) result[i] = (byte) Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16); - } + return result; } @@ -71,7 +71,6 @@ public class EggUtils { if (num != -1) { result = result.multiply(twentySix); result = result.add(BigInteger.valueOf(num)); - } } return result; @@ -80,9 +79,8 @@ public class EggUtils { private static int convertChar(char c) { c = StringUtils.goLowerCase(c); - if (c >= 'a' && c <= 'z') { + if (c >= 'a' && c <= 'z') return c - 'a'; - } return -1; } @@ -91,10 +89,8 @@ public class EggUtils { int pos = 0; for (int i = 0; i < result.length; i++) { result[i] = (byte) (data[i] ^ key[pos++]); - if (pos == key.length) { + if (pos == key.length) pos = 0; - } - } return result; } diff --git a/src/net/sourceforge/plantuml/hcl/HclDiagramFactory.java b/src/net/sourceforge/plantuml/hcl/HclDiagramFactory.java index 51075f19e..4c724dc19 100644 --- a/src/net/sourceforge/plantuml/hcl/HclDiagramFactory.java +++ b/src/net/sourceforge/plantuml/hcl/HclDiagramFactory.java @@ -49,6 +49,7 @@ import net.sourceforge.plantuml.json.JsonValue; import net.sourceforge.plantuml.jsondiagram.JsonDiagram; import net.sourceforge.plantuml.jsondiagram.StyleExtractor; import net.sourceforge.plantuml.log.Logme; +import net.sourceforge.plantuml.yaml.Highlighted; public class HclDiagramFactory extends PSystemAbstractFactory { @@ -58,7 +59,7 @@ public class HclDiagramFactory extends PSystemAbstractFactory { @Override public Diagram createSystem(UmlSource source, Map skinParam) { - final List highlighted = new ArrayList<>(); + final List highlighted = new ArrayList<>(); JsonValue data = null; StyleExtractor styleExtractor = null; try { diff --git a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java index ff025ecad..42b14b7ca 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java +++ b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java @@ -62,14 +62,15 @@ import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.hand.UGraphicHandwritten; +import net.sourceforge.plantuml.yaml.Highlighted; public class JsonDiagram extends TitledDiagram { private final JsonValue root; - private final List highlighted; + private final List highlighted; private final boolean handwritten; - public JsonDiagram(UmlSource source, UmlDiagramType type, JsonValue json, List highlighted, + public JsonDiagram(UmlSource source, UmlDiagramType type, JsonValue json, List highlighted, StyleExtractor styleExtractor) { super(source, type, null); this.handwritten = styleExtractor.isHandwritten(); diff --git a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagramFactory.java b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagramFactory.java index b24ead5ca..6a7704f35 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagramFactory.java +++ b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagramFactory.java @@ -49,6 +49,9 @@ import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.json.Json; import net.sourceforge.plantuml.json.JsonValue; import net.sourceforge.plantuml.json.ParseException; +import net.sourceforge.plantuml.log.Logme; +import net.sourceforge.plantuml.style.parser.StyleParsingException; +import net.sourceforge.plantuml.yaml.Highlighted; public class JsonDiagramFactory extends PSystemAbstractFactory { @@ -58,7 +61,7 @@ public class JsonDiagramFactory extends PSystemAbstractFactory { @Override public Diagram createSystem(UmlSource source, Map skinParam) { - final List highlighted = new ArrayList<>(); + final List highlighted = new ArrayList<>(); StyleExtractor styleExtractor = null; JsonValue json; try { @@ -72,8 +75,8 @@ public class JsonDiagramFactory extends PSystemAbstractFactory { break; if (line.startsWith("#")) { - if (line.startsWith("#highlight ")) { - highlighted.add(line.substring("#highlight ".length()).trim()); + if (Highlighted.matchesDefinition(line)) { + highlighted.add(Highlighted.build(line)); continue; } } else { @@ -87,7 +90,11 @@ public class JsonDiagramFactory extends PSystemAbstractFactory { } final JsonDiagram result = new JsonDiagram(source, UmlDiagramType.JSON, json, highlighted, styleExtractor); if (styleExtractor != null) - styleExtractor.applyStyles(result.getSkinParam()); + try { + styleExtractor.applyStyles(result.getSkinParam()); + } catch (StyleParsingException e) { + Logme.error(e); + } return result; } diff --git a/src/net/sourceforge/plantuml/jsondiagram/SmetanaForJson.java b/src/net/sourceforge/plantuml/jsondiagram/SmetanaForJson.java index b69d513fe..e6e337faa 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/SmetanaForJson.java +++ b/src/net/sourceforge/plantuml/jsondiagram/SmetanaForJson.java @@ -63,6 +63,7 @@ import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.yaml.Highlighted; import smetana.core.CString; import smetana.core.Macro; import smetana.core.Z; @@ -125,24 +126,8 @@ public class SmetanaForJson { .getMergedStyle(skinParam.getCurrentStyleBuilder()); } - private Style getStyleNodeHeader() { - return StyleSignatureBasic.of(SName.root, SName.element, getDiagramType(), SName.header, SName.node) - .getMergedStyle(skinParam.getCurrentStyleBuilder()); - } - - private Style getStyleNodeHighlight() { - return StyleSignatureBasic.of(SName.root, SName.element, getDiagramType(), SName.node, SName.highlight) - .getMergedStyle(skinParam.getCurrentStyleBuilder()); - } - - private Style getStyleNodeHeaderHighlight() { - return StyleSignatureBasic.of(SName.root, SName.element, getDiagramType(), SName.header, SName.node, SName.highlight) - .getMergedStyle(skinParam.getCurrentStyleBuilder()); - } - - private ST_Agnode_s manageOneNode(JsonValue current, List highlighted) { - final TextBlockJson block = new TextBlockJson(skinParam, current, highlighted, getStyleNode(), - getStyleNodeHighlight(), getStyleNodeHeader(), getStyleNodeHeaderHighlight()); + private ST_Agnode_s manageOneNode(JsonValue current, List highlighted) { + final TextBlockJson block = new TextBlockJson(skinParam, current, highlighted); final ST_Agnode_s node1 = createNode(block.calculateDimension(stringBounder), block.size(), current.isArray(), (int) block.getWidthColA(stringBounder), (int) block.getWidthColB(stringBounder)); nodes.add(new InternalNode(block, node1)); @@ -151,7 +136,7 @@ public class SmetanaForJson { for (int i = 0; i < children.size(); i++) { final JsonValue tmp = children.get(i); if (tmp != null) { - final ST_Agnode_s childBloc = manageOneNode(tmp, removeOneLevel(keys.get(i), highlighted)); + final ST_Agnode_s childBloc = manageOneNode(tmp, upOneLevel(keys.get(i), highlighted)); final ST_Agedge_s edge = createEdge(node1, childBloc, i); edges.add(edge); } @@ -160,49 +145,41 @@ public class SmetanaForJson { } - private List removeOneLevel(String key, List list) { - final List result = new ArrayList<>(); - for (String tmp : list) { - if (tmp.startsWith("\"" + key + "\"") == false) { - continue; - } - tmp = tmp.trim().replaceFirst("\"([^\"]+)\"", "").trim(); - if (tmp.length() > 0) { - tmp = tmp.substring(1).trim(); - result.add(tmp); - } + private List upOneLevel(String key, List list) { + final List result = new ArrayList<>(); + for (Highlighted tmp : list) { + final Highlighted parent = tmp.upOneLevel(key); + if (parent != null) + result.add(parent); } return Collections.unmodifiableList(result); } - public void drawMe(JsonValue root, List highlighted) { + public void drawMe(JsonValue root, List highlighted) { initGraph(root, highlighted); double max = 0; - for (InternalNode node : nodes) { + for (InternalNode node : nodes) max = Math.max(max, node.getMaxX()); - } + xMirror = new Mirror(max); - for (InternalNode node : nodes) { - node.block.drawU( - getStyleNode().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()) - .apply(getPosition(node.node))); - } + for (InternalNode node : nodes) + node.block.drawU(getStyleNode().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()) + .apply(getPosition(node.node))); + final HColor color = getStyleArrow().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()); for (ST_Agedge_s edge : edges) { final JsonCurve curve = getCurve(edge, 13); curve.drawCurve(color, getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet())); - curve.drawSpot( - getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()) - .apply(color.bg())); + curve.drawSpot(getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()).apply(color.bg())); } } - private void initGraph(JsonValue root, List highlighted) { - if (g != null) { + private void initGraph(JsonValue root, List highlighted) { + if (g != null) return; - } + Z.open(); try { @@ -268,9 +245,8 @@ public class SmetanaForJson { final int lineHeight = 0; final String dotLabel = getDotLabel(size, isArray, colAwidth - 8, colBwidth - 8, lineHeight); - if (size > 0) { + if (size > 0) agsafeset(node, new CString("label"), new CString(dotLabel), new CString("")); - } StringBuilder sb = new StringBuilder(); sb.append("N" + node.UID + " ["); @@ -284,19 +260,17 @@ public class SmetanaForJson { private String getDotLabel(int size, boolean isArray, int widthA, int widthB, int height) { final StringBuilder sb = new StringBuilder(""); - if (isArray == false) { - // "+height+" + if (isArray == false) sb.append("{_dim_" + height + "_" + widthA + "_|{"); - } + for (int i = 0; i < size; i++) { sb.append(""); sb.append("_dim_" + height + "_" + widthB + "_"); if (i < size - 1) sb.append("|"); } - if (isArray == false) { + if (isArray == false) sb.append("}}"); - } return sb.toString(); } diff --git a/src/net/sourceforge/plantuml/jsondiagram/StyleExtractor.java b/src/net/sourceforge/plantuml/jsondiagram/StyleExtractor.java index 796cbb766..dfa93a975 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/StyleExtractor.java +++ b/src/net/sourceforge/plantuml/jsondiagram/StyleExtractor.java @@ -43,6 +43,7 @@ import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.parser.StyleParser; +import net.sourceforge.plantuml.style.parser.StyleParsingException; import net.sourceforge.plantuml.utils.BlocLines; import net.sourceforge.plantuml.utils.StringLocated; @@ -108,13 +109,12 @@ public class StyleExtractor { return line.getString().trim().equals(""); } - public void applyStyles(ISkinParam skinParam) { + public void applyStyles(ISkinParam skinParam) throws StyleParsingException { if (style.size() > 0) { final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder(); final BlocLines blocLines = BlocLines.from(style); - for (Style modifiedStyle : StyleParser.parse(blocLines.subExtract(1, 1), styleBuilder)) { + for (Style modifiedStyle : StyleParser.parse(blocLines.subExtract(1, 1), styleBuilder)) skinParam.muteStyle(modifiedStyle); - } } } diff --git a/src/net/sourceforge/plantuml/jsondiagram/TextBlockJson.java b/src/net/sourceforge/plantuml/jsondiagram/TextBlockJson.java index fd75aba58..8f69b003d 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/TextBlockJson.java +++ b/src/net/sourceforge/plantuml/jsondiagram/TextBlockJson.java @@ -41,6 +41,7 @@ import java.util.List; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineBreakStrategy; +import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.awt.geom.XDimension2D; import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.cucadiagram.Display; @@ -57,38 +58,41 @@ import net.sourceforge.plantuml.json.JsonValue; import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.style.StyleBuilder; +import net.sourceforge.plantuml.style.StyleSignature; +import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.yaml.Highlighted; //See TextBlockMap public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcolored { private final List lines = new ArrayList<>(); - private final Style styleNode; - private final Style styleNodeHightlight; - private final Style styleNodeHeader; - private final Style styleNodeHeaderHighlight; private final ISkinParam skinParam; private double totalWidth; private final JsonValue root; + private final StyleBuilder styleBuilder; + private final SName diagramType; + static class Line { final TextBlock b1; final TextBlock b2; - final boolean highlighted; + final Highlighted highlighted; - Line(TextBlock b1, TextBlock b2, boolean highlighted) { + Line(TextBlock b1, TextBlock b2, Highlighted highlighted) { this.b1 = b1; this.b2 = b2; this.highlighted = highlighted; } - Line(TextBlock b1, boolean highlighted) { + Line(TextBlock b1, Highlighted highlighted) { this(b1, null, highlighted); } @@ -102,24 +106,18 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol } - private HColor getBackColor() { - return styleNodeHightlight.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet()); - } - - TextBlockJson(ISkinParam skinParam, JsonValue root, List allHighlighteds, Style styleNode, - Style styleNodeHightlight, Style styleNodeHeader, Style styleNodeHeaderHighlight) { + TextBlockJson(ISkinParam skinParam, JsonValue root, List allHighlighteds) { + this.styleBuilder = skinParam.getCurrentStyleBuilder(); + this.diagramType = skinParam.getUmlDiagramType() == UmlDiagramType.JSON ? SName.jsonDiagram : SName.yamlDiagram; this.skinParam = skinParam; - this.styleNode = styleNode; - this.styleNodeHeaderHighlight = styleNodeHeaderHighlight; - this.styleNodeHightlight = styleNodeHightlight; - this.styleNodeHeader = styleNodeHeader; + this.root = root; if (root instanceof JsonObject) for (Member member : (JsonObject) root) { final String key = member.getName(); final String value = getShortString(member.getValue()); - final boolean highlighted = isHighlighted(key, allHighlighteds); + final Highlighted highlighted = isHighlighted(key, allHighlighteds); final TextBlock block1 = getTextBlock(getStyleToUse(true, highlighted), key); final TextBlock block2 = getTextBlock(getStyleToUse(false, highlighted), value); this.lines.add(new Line(block1, block2, highlighted)); @@ -127,7 +125,7 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol if (root instanceof JsonArray) { int i = 0; for (JsonValue value : (JsonArray) root) { - final boolean highlighted = isHighlighted("" + i, allHighlighteds); + final Highlighted highlighted = isHighlighted("" + i, allHighlighteds); final TextBlock block2 = getTextBlock(getStyleToUse(false, highlighted), getShortString(value)); this.lines.add(new Line(block2, highlighted)); i++; @@ -135,25 +133,29 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol } } - private Style getStyleToUse(boolean header, boolean highlighted) { - if (header && highlighted) - return styleNodeHeaderHighlight; + private Style getStyleToUse(boolean header, Highlighted highlighted) { + final StyleSignature signature; + if (header && highlighted != null) + signature = StyleSignatureBasic + .of(SName.root, SName.element, diagramType, SName.header, SName.node, SName.highlight) + .withTOBECHANGED(highlighted.getStereotype()); + else if (highlighted != null) + signature = StyleSignatureBasic.of(SName.root, SName.element, diagramType, SName.node, SName.highlight) + .withTOBECHANGED(highlighted.getStereotype()); + else if (header) + signature = StyleSignatureBasic.of(SName.root, SName.element, diagramType, SName.header, SName.node); + else + signature = StyleSignatureBasic.of(SName.root, SName.element, diagramType, SName.node); - if (highlighted) - return styleNodeHightlight; - - if (header) - return styleNodeHeader; - - return styleNode; + return signature.getMergedStyle(styleBuilder); } - private boolean isHighlighted(String key, List highlighted) { - for (String tmp : highlighted) - if (tmp.trim().equals("\"" + key + "\"")) - return true; + private Highlighted isHighlighted(String key, List highlighted) { + for (Highlighted tmp : highlighted) + if (tmp.isKeyHighlight(key)) + return tmp; - return false; + return null; } public int size() { @@ -260,6 +262,8 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol final double widthColB = getWidthColB(stringBounder); double y = 0; + final Style styleNode = StyleSignatureBasic.of(SName.root, SName.element, diagramType, SName.node) + .getMergedStyle(styleBuilder); final UGraphic ugNode = styleNode.applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()); for (Line line : lines) { final double heightOfRow = line.getHeightOfRow(stringBounder); @@ -283,9 +287,14 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol for (Line line : lines) { final UGraphic ugline = ugSeparator.apply(UTranslate.dy(y)); final double heightOfRow = line.getHeightOfRow(stringBounder); - if (line.highlighted) { + if (line.highlighted != null) { final URectangle back = new URectangle(trueWidth - 2, heightOfRow).rounded(4); - ugline.apply(getBackColor()).apply(getBackColor().bg()).apply(new UTranslate(1.5, 0)).draw(back); + final Style styleNodeHighlight = StyleSignatureBasic + .of(SName.root, SName.element, diagramType, SName.node, SName.highlight) + .withTOBECHANGED(line.highlighted.getStereotype()).getMergedStyle(styleBuilder); + final HColor cellBackColor = styleNodeHighlight.value(PName.BackGroundColor) + .asColor(skinParam.getIHtmlColorSet()); + ugline.apply(cellBackColor).apply(cellBackColor.bg()).apply(new UTranslate(1.5, 0)).draw(back); } if (y > 0) diff --git a/src/net/sourceforge/plantuml/nwdiag/core/NServer.java b/src/net/sourceforge/plantuml/nwdiag/core/NServer.java index 045b2dd44..226a53cc8 100644 --- a/src/net/sourceforge/plantuml/nwdiag/core/NServer.java +++ b/src/net/sourceforge/plantuml/nwdiag/core/NServer.java @@ -57,6 +57,8 @@ import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.svek.PackageStyle; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class NServer { @@ -65,6 +67,7 @@ public class NServer { private USymbol shape = USymbols.RECTANGLE; private final String name; private String description; + private String backcolor; private final NBar bar; private boolean printFirstLink = true; @@ -86,12 +89,12 @@ public class NServer { } private TextBlock toTextBlock(String s, ISkinParam skinParam, SName sname) { - if (s == null) + if (s == null) return null; - - if (s.length() == 0) + + if (s.length() == 0) return TextBlockUtils.empty(0, 0); - + s = s.replace(", ", "\\n"); return Display.getWithNewlines(s).create(getFontConfiguration(skinParam, sname), HorizontalAlignment.LEFT, skinParam); @@ -110,13 +113,18 @@ public class NServer { public LinkedElement getLinkedElement(double topMargin, Map conns, List networks, ISkinParam skinParam) { final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder(); - final SymbolContext symbolContext = getStyleDefinition(SName.server).getMergedStyle(styleBuilder) + SymbolContext symbolContext = getStyleDefinition(SName.server).getMergedStyle(styleBuilder) .getSymbolContext(skinParam.getIHtmlColorSet()); + if (backcolor != null) + try { + final HColor back = skinParam.getIHtmlColorSet().getColor(backcolor); + symbolContext = symbolContext.withBackColor(back); + } catch (NoSuchColorException e) { + } final Map conns2 = new LinkedHashMap(); - for (Entry ent : conns.entrySet()) + for (Entry ent : conns.entrySet()) conns2.put(ent.getKey(), toTextBlock(ent.getValue(), skinParam, SName.arrow)); - final TextBlock desc = toTextBlock(getDescription(), skinParam, SName.server); final TextBlock box = getShape().asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), @@ -131,9 +139,9 @@ public class NServer { public void connectTo(Network network, String address) { if (address == null) address = ""; - if (address.length() == 0 && connections.containsKey(network)) + if (address.length() == 0 && connections.containsKey(network)) return; - + connections.put(network, address); if (bar.getStart() == null) bar.addStage(network.getNstage()); @@ -142,14 +150,18 @@ public class NServer { } public void updateProperties(Map props) { - final String description = props.get("description"); - if (description != null) - this.setDescription(description); - + if (props.get("description") != null) + this.description = props.get("description"); + this.backcolor = props.get("color"); + final String shape = props.get("shape"); - if (shape != null) - this.setShape(shape); - + if (shape != null) { + final USymbol shapeFromString = USymbols.fromString(shape, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE, + PackageStyle.RECTANGLE); + if (shapeFromString != null) + this.shape = shapeFromString; + } + } @Override @@ -171,22 +183,10 @@ public class NServer { return description; } - public final void setDescription(String description) { - this.description = description; - } - public final String getName() { return name; } - public final void setShape(String shapeName) { - final USymbol shapeFromString = USymbols.fromString(shapeName, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE, - PackageStyle.RECTANGLE); - if (shapeFromString != null) { - this.shape = shapeFromString; - } - } - public final USymbol getShape() { return shape; } diff --git a/src/net/sourceforge/plantuml/regex/RegexExpression.java b/src/net/sourceforge/plantuml/regex/RegexExpression.java index a7dcd478c..84b6992e6 100644 --- a/src/net/sourceforge/plantuml/regex/RegexExpression.java +++ b/src/net/sourceforge/plantuml/regex/RegexExpression.java @@ -54,11 +54,11 @@ public class RegexExpression { result.add(new ReToken(ReTokenType.ANCHOR, s)); } else if (isEscapedChar(it)) { result.add(new ReToken(ReTokenType.ESCAPED_CHAR, "" + it.peek(1))); - it.next(); - it.next(); + it.jump(); + it.jump(); } else if (current == '|') { result.add(new ReToken(ReTokenType.ALTERNATIVE, "|")); - it.next(); + it.jump(); } else if (current == '[') { final String s = readGroup(it); result.add(new ReToken(ReTokenType.GROUP, s)); @@ -67,7 +67,7 @@ public class RegexExpression { result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, s)); } else if (current == ')') { result.add(new ReToken(ReTokenType.PARENTHESIS_CLOSE, ")")); - it.next(); + it.jump(); } else if (isStartQuantifier(it)) { final String s = readQuantifier(it); result.add(new ReToken(ReTokenType.QUANTIFIER, s)); @@ -76,7 +76,7 @@ public class RegexExpression { result.add(new ReToken(ReTokenType.CLASS, s)); } else if (isSimpleLetter(current)) { result.add(new ReToken(ReTokenType.SIMPLE_CHAR, "" + current)); - it.next(); + it.jump(); } else { throw new IllegalStateException(); } @@ -95,17 +95,17 @@ public class RegexExpression { private static String readOpenParenthesis(CharInspector it) { final char current0 = it.peek(0); - it.next(); + it.jump(); final StringBuilder result = new StringBuilder(); result.append(current0); if (it.peek(0) == '?' && it.peek(1) == ':') { - it.next(); - it.next(); + it.jump(); + it.jump(); result.append("?:"); } if (it.peek(0) == '?' && it.peek(1) == '!') { - it.next(); - it.next(); + it.jump(); + it.jump(); result.append("?!"); } return result.toString(); @@ -120,20 +120,20 @@ public class RegexExpression { private static String readQuantifier(CharInspector it) { final char current0 = it.peek(0); - it.next(); + it.jump(); final StringBuilder result = new StringBuilder(); result.append(current0); if (current0 == '{') while (it.peek(0) != 0) { final char ch = it.peek(0); result.append(ch); - it.next(); + it.jump(); if (ch == '}') break; } if (it.peek(0) == '?') { result.append('?'); - it.next(); + it.jump(); } return result.toString(); } @@ -154,17 +154,17 @@ public class RegexExpression { final char current0 = it.peek(0); if (current0 != '[') throw new IllegalStateException(); - it.next(); + it.jump(); final StringBuilder result = new StringBuilder(); while (it.peek(0) != 0) { char ch = it.peek(0); - it.next(); + it.jump(); if (ch == ']') break; result.append(ch); if (ch == '\\') { ch = it.peek(0); - it.next(); + it.jump(); result.append(ch); } @@ -175,13 +175,13 @@ public class RegexExpression { private static String readClass(CharInspector it) { final char current0 = it.peek(0); if (current0 == '.') { - it.next(); + it.jump(); return "" + current0; } if (current0 == '\\') { - it.next(); + it.jump(); final String result = "" + current0 + it.peek(0); - it.next(); + it.jump(); return result; } throw new IllegalStateException(); @@ -218,13 +218,13 @@ public class RegexExpression { private static String readAnchor(CharInspector it) { final char current0 = it.peek(0); if (current0 == '^' || current0 == '$') { - it.next(); + it.jump(); return "" + current0; } if (current0 == '\\') { - it.next(); + it.jump(); final String result = "" + current0 + it.peek(0); - it.next(); + it.jump(); return result; } throw new IllegalStateException(); diff --git a/src/net/sourceforge/plantuml/salt/Dictionary.java b/src/net/sourceforge/plantuml/salt/Dictionary.java index 153f1fea0..d455eca2a 100644 --- a/src/net/sourceforge/plantuml/salt/Dictionary.java +++ b/src/net/sourceforge/plantuml/salt/Dictionary.java @@ -41,7 +41,6 @@ import java.util.Objects; import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinSimple; -import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.SpriteContainer; import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.creole.Parser; @@ -115,11 +114,6 @@ public class Dictionary implements SpriteContainer, ISkinSimple { } - @Override - public LineBreakStrategy wrapWidth() { - return LineBreakStrategy.NONE; - } - @Override public void copyAllFrom(Map other) { throw new UnsupportedOperationException(); diff --git a/src/net/sourceforge/plantuml/sdot/CucaDiagramFileMakerSmetana.java b/src/net/sourceforge/plantuml/sdot/CucaDiagramFileMakerSmetana.java index 6efb21052..fa3c42eea 100644 --- a/src/net/sourceforge/plantuml/sdot/CucaDiagramFileMakerSmetana.java +++ b/src/net/sourceforge/plantuml/sdot/CucaDiagramFileMakerSmetana.java @@ -62,7 +62,6 @@ import h.ST_Agrec_s; import h.ST_GVC_s; import h.ST_boxf; import net.sourceforge.plantuml.FileFormatOption; -import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; @@ -87,6 +86,9 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.log.Logme; +import net.sourceforge.plantuml.style.SName; +import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Cluster; import net.sourceforge.plantuml.svek.ClusterHeader; @@ -435,10 +437,17 @@ public class CucaDiagramFileMakerSmetana implements CucaDiagramFileMaker { this.exportGroups(cluster1, group); } + private Style getStyle() { + return StyleSignatureBasic + .of(SName.root, SName.element, diagram.getUmlDiagramType().getStyleName(), SName.arrow) + .getMergedStyle(diagram.getSkinParam().getCurrentStyleBuilder()); + } + private TextBlock getLabel(Link link) { final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1; ISkinParam skinParam = diagram.getSkinParam(); - final FontConfiguration labelFont = FontConfiguration.create(skinParam, FontParam.ARROW, null); + final Style style = getStyle(); + final FontConfiguration labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet()); final TextBlock label = link.getLabel().create(labelFont, skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam); if (TextBlockUtils.isEmpty(label, stringBounder)) @@ -454,7 +463,8 @@ public class CucaDiagramFileMakerSmetana implements CucaDiagramFileMaker { final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1; ISkinParam skinParam = diagram.getSkinParam(); - final FontConfiguration labelFont = FontConfiguration.create(skinParam, FontParam.ARROW, null); + final Style style = getStyle(); + final FontConfiguration labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet()); final TextBlock label = Display.getWithNewlines(tmp).create(labelFont, skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam); if (TextBlockUtils.isEmpty(label, stringBounder)) diff --git a/src/net/sourceforge/plantuml/sdot/SmetanaPath.java b/src/net/sourceforge/plantuml/sdot/SmetanaPath.java index 32d608b2b..ad24378b9 100644 --- a/src/net/sourceforge/plantuml/sdot/SmetanaPath.java +++ b/src/net/sourceforge/plantuml/sdot/SmetanaPath.java @@ -42,6 +42,7 @@ import h.ST_pointf; import h.ST_splines; import h.ST_textlabel_t; import net.sourceforge.plantuml.LineParam; +import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.awt.geom.XPoint2D; import net.sourceforge.plantuml.cucadiagram.ICucaDiagram; import net.sourceforge.plantuml.cucadiagram.Link; @@ -50,9 +51,9 @@ import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.posimo.DotPath; -import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.SName; +import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.svek.extremity.ExtremityFactory; import net.sourceforge.plantuml.ugraphic.UEllipse; @@ -73,7 +74,6 @@ public class SmetanaPath implements UDrawable { private final TextBlock label; private final TextBlock headLabel; private final TextBlock tailLabel; - private final Rose rose = new Rose(); public SmetanaPath(Link link, ST_Agedge_s edge, YMirror ymirror, ICucaDiagram diagram, TextBlock label, TextBlock tailLabel, TextBlock headLabel) { @@ -91,10 +91,7 @@ public class SmetanaPath implements UDrawable { if (link.isHidden()) return; - HColor color = StyleSignatureBasic - .of(SName.root, SName.element, diagram.getUmlDiagramType().getStyleName(), SName.arrow) - .getMergedStyle(diagram.getSkinParam().getCurrentStyleBuilder()).value(PName.LineColor) - .asColor(diagram.getSkinParam().getIHtmlColorSet()); + HColor color = getStyle().value(PName.LineColor).asColor(diagram.getSkinParam().getIHtmlColorSet()); if (this.link.getColors() != null) { final HColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE); @@ -113,9 +110,17 @@ public class SmetanaPath implements UDrawable { if (link.getColors() != null && link.getColors().getSpecificLineStroke() != null) stroke = link.getColors().getSpecificLineStroke(); + final Url url = link.getUrl(); + if (url != null) + ug.startUrl(url); + ug.apply(stroke).apply(color).draw(dotPath); printExtremityAtStart(ug.apply(color)); printExtremityAtEnd(ug.apply(color)); + + if (url != null) + ug.closeUrl(); + } if (getLabelRectangleTranslate("label") != null) label.drawU(ug.apply(getLabelRectangleTranslate("label"))); @@ -130,6 +135,12 @@ public class SmetanaPath implements UDrawable { } + private Style getStyle() { + return StyleSignatureBasic + .of(SName.root, SName.element, diagram.getUmlDiagramType().getStyleName(), SName.arrow) + .getMergedStyle(diagram.getSkinParam().getCurrentStyleBuilder()); + } + private void printExtremityAtStart(UGraphic ug) { final ExtremityFactory extremityFactory2 = link.getType().getDecor2() .getExtremityFactoryComplete(diagram.getSkinParam().getBackgroundColor()); diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java index 4c4b066ed..9b7a41354 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java @@ -64,7 +64,7 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements public ComponentRoseNote(Style style, Display strings, double paddingX, double paddingY, ISkinSimple spriteContainer, HorizontalAlignment textAlignment, HorizontalAlignment position, Colors colors) { - super(style, spriteContainer.wrapWidth(), textAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, + super(style, style.wrapWidth(), textAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, strings, true); this.paddingX = paddingX; this.paddingY = paddingY; diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteBox.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteBox.java index 7e6dfce9f..d1ae4f03c 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteBox.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteBox.java @@ -55,7 +55,7 @@ final public class ComponentRoseNoteBox extends AbstractTextualComponent { private final double roundCorner; public ComponentRoseNoteBox(Style style, Display strings, ISkinSimple spriteContainer, Colors colors) { - super(style, spriteContainer.wrapWidth(), 4, 4, 4, spriteContainer, strings, false); + super(style, style.wrapWidth(), 4, 4, 4, spriteContainer, strings, false); this.symbolContext = style.getSymbolContext(getIHtmlColorSet(), colors); this.roundCorner = style.value(PName.RoundCorner).asInt(false); diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java index 18b6e8411..330595871 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java @@ -54,7 +54,7 @@ final public class ComponentRoseNoteHexagonal extends AbstractTextualComponent { private final SymbolContext symbolContext; public ComponentRoseNoteHexagonal(Style style, Display strings, ISkinSimple spriteContainer, Colors colors) { - super(style, spriteContainer.wrapWidth(), 12, 12, 4, spriteContainer, strings, false); + super(style, style.wrapWidth(), 12, 12, 4, spriteContainer, strings, false); this.symbolContext = style.getSymbolContext(getIHtmlColorSet(), colors); diff --git a/src/net/sourceforge/plantuml/style/CommandStyleImport.java b/src/net/sourceforge/plantuml/style/CommandStyleImport.java index 12faaad47..3aa20629a 100644 --- a/src/net/sourceforge/plantuml/style/CommandStyleImport.java +++ b/src/net/sourceforge/plantuml/style/CommandStyleImport.java @@ -48,6 +48,7 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.style.parser.StyleParser; +import net.sourceforge.plantuml.style.parser.StyleParsingException; import net.sourceforge.plantuml.utils.BlocLines; import net.sourceforge.plantuml.utils.LineLocation; @@ -84,17 +85,19 @@ public class CommandStyleImport extends SingleLineCommand2 { lines = BlocLines.load(f, location); } else { final InputStream internalIs = StyleLoader.class.getResourceAsStream("/skin/" + path); - if (internalIs != null) { + if (internalIs != null) lines = BlocLines.load(internalIs, location); - } + } - if (lines == null) { + if (lines == null) return CommandExecutionResult.error("Cannot read: " + path); - } + final StyleBuilder styleBuilder = diagram.getSkinParam().getCurrentStyleBuilder(); - for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder)) { + for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder)) diagram.getSkinParam().muteStyle(modifiedStyle); - } + + } catch (StyleParsingException e) { + return CommandExecutionResult.error("Error in style definition: " + e.getMessage()); } catch (IOException e) { return CommandExecutionResult.error("Cannot read: " + path); } diff --git a/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java b/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java index 34d83201b..51aebb968 100644 --- a/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java +++ b/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java @@ -45,6 +45,7 @@ import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.style.parser.StyleParser; +import net.sourceforge.plantuml.style.parser.StyleParsingException; import net.sourceforge.plantuml.utils.BlocLines; public class CommandStyleMultilinesCSS extends CommandMultilines2 { @@ -57,7 +58,7 @@ public class CommandStyleMultilinesCSS extends CommandMultilines2 @Override public String getPatternEnd() { - return "^[%s]*\\[%s]*$"; + return "^[%s]*\\[%s]*$"; } private static IRegex getRegexConcat() { @@ -75,6 +76,8 @@ public class CommandStyleMultilinesCSS extends CommandMultilines2 ((SkinParam) diagram.getSkinParam()).applyPendingStyleMigration(); return CommandExecutionResult.ok(); + } catch (StyleParsingException e) { + return CommandExecutionResult.error("Error in style definition: " + e.getMessage()); } catch (NoStyleAvailableException e) { // Logme.error(e); return CommandExecutionResult.error("General failure: no style available."); diff --git a/src/net/sourceforge/plantuml/style/FromSkinparamToStyle.java b/src/net/sourceforge/plantuml/style/FromSkinparamToStyle.java index cda3e8a61..adf03e0f4 100644 --- a/src/net/sourceforge/plantuml/style/FromSkinparamToStyle.java +++ b/src/net/sourceforge/plantuml/style/FromSkinparamToStyle.java @@ -235,6 +235,9 @@ public class FromSkinparamToStyle { // addConvert("sequenceStereotypeFontName", PName.FontName, SName.stereotype); addConvert("lifelineStrategy", PName.LineStyle, SName.lifeLine); + addConvert("wrapWidth", PName.MaximumWidth, SName.element); + addConvert("HyperlinkUnderline", PName.HyperlinkUnderlineThickness, SName.element); + } @@ -282,6 +285,9 @@ public class FromSkinparamToStyle { } else if (key.equals("lifelinestrategy")) { if (value.equalsIgnoreCase("solid")) value = "0"; + } else if (key.equals("hyperlinkunderline")) { + if (value.equalsIgnoreCase("false")) + value = "0"; } if (value.equalsIgnoreCase("right:right")) diff --git a/src/net/sourceforge/plantuml/style/Style.java b/src/net/sourceforge/plantuml/style/Style.java index 41d78014f..333486d7b 100644 --- a/src/net/sourceforge/plantuml/style/Style.java +++ b/src/net/sourceforge/plantuml/style/Style.java @@ -227,7 +227,7 @@ public class Style { Style result = this.eventuallyOverride(PName.LineThickness, stroke.getThickness()); final double space = stroke.getDashSpace(); final double visible = stroke.getDashVisible(); - result = result.eventuallyOverride(PName.LineStyle, "" + visible + ";" + space); + result = result.eventuallyOverride(PName.LineStyle, "" + visible + "-" + space); return result; } diff --git a/src/net/sourceforge/plantuml/style/StyleLoader.java b/src/net/sourceforge/plantuml/style/StyleLoader.java index e16c3442b..9095bd5d3 100644 --- a/src/net/sourceforge/plantuml/style/StyleLoader.java +++ b/src/net/sourceforge/plantuml/style/StyleLoader.java @@ -45,6 +45,7 @@ import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.style.parser.StyleParser; +import net.sourceforge.plantuml.style.parser.StyleParsingException; import net.sourceforge.plantuml.utils.BlocLines; import net.sourceforge.plantuml.utils.LineLocationImpl; import net.sourceforge.plantuml.utils.Log; @@ -59,7 +60,7 @@ public class StyleLoader { private StyleBuilder styleBuilder; - public StyleBuilder loadSkin(String filename) throws IOException { + public StyleBuilder loadSkin(String filename) throws IOException, StyleParsingException { this.styleBuilder = new StyleBuilder(skinParam); final InputStream internalIs = getInputStreamForStyle(filename); @@ -101,7 +102,7 @@ public class StyleLoader { return internalIs; } - private void loadSkinInternal(final BlocLines lines) { + private void loadSkinInternal(final BlocLines lines) throws StyleParsingException { for (Style newStyle : StyleParser.parse(lines, styleBuilder)) this.styleBuilder.loadInternal(newStyle.getSignature(), newStyle); } diff --git a/src/net/sourceforge/plantuml/style/parser/Context.java b/src/net/sourceforge/plantuml/style/parser/Context.java index 0273fd333..3d1229f3f 100644 --- a/src/net/sourceforge/plantuml/style/parser/Context.java +++ b/src/net/sourceforge/plantuml/style/parser/Context.java @@ -38,29 +38,38 @@ package net.sourceforge.plantuml.style.parser; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.EnumMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Map; +import net.sourceforge.plantuml.style.PName; +import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.style.StyleLoader; import net.sourceforge.plantuml.style.StyleSignatureBasic; +import net.sourceforge.plantuml.style.Value; class Context { private final List data = new ArrayList(); + private final Map map = new EnumMap<>(PName.class); + private Context parent; public Context push(String newString) { + if (newString.startsWith(":")) + newString = newString.substring(1); final Context result = new Context(); result.data.addAll(this.data); result.data.add(newString); + result.parent = this; return result; } public Context pop() { if (size() == 0) throw new IllegalStateException(); - final Context result = new Context(); - result.data.addAll(this.data.subList(0, this.data.size() - 1)); - return result; + return this.parent; } @Override @@ -98,4 +107,22 @@ class Context { return Collections.unmodifiableCollection(results); } + public void putInContext(PName key, Value value) { + map.put(key, value); + } + + public Collection