Version 1.2023.0

This commit is contained in:
Arnaud Roques 2023-01-09 20:13:37 +01:00
parent 0ed5f14c32
commit a5d39f6dda
75 changed files with 1450 additions and 444 deletions

View File

@ -394,7 +394,7 @@ yamlDiagram,jsonDiagram {
LineColor black LineColor black
arrow { arrow {
LineThickness 1 LineThickness 1
LineStyle 3;3 LineStyle 3-3
} }
node { node {
LineThickness 1.5 LineThickness 1.5
@ -462,7 +462,7 @@ timingDiagram {
highlight { highlight {
BackgroundColor #e BackgroundColor #e
LineThickness 2 LineThickness 2
LineStyle 4;4 LineStyle 4-4
} }
} }

View File

@ -460,7 +460,7 @@ yamlDiagram,jsonDiagram {
LineColor black LineColor black
arrow { arrow {
LineThickness 1 LineThickness 1
LineStyle 3;3 LineStyle 3-3
} }
node { node {
LineThickness 1.5 LineThickness 1.5
@ -517,7 +517,7 @@ timingDiagram {
highlight { highlight {
BackgroundColor #e BackgroundColor #e
LineThickness 2 LineThickness 2
LineStyle 4;4 LineStyle 4-4
} }
} }

View File

@ -114,8 +114,6 @@ public interface ISkinParam extends ISkinSimple {
public LineBreakStrategy maxMessageSize(); public LineBreakStrategy maxMessageSize();
public LineBreakStrategy wrapWidth();
public LineBreakStrategy swimlaneWrapTitleWidth(); public LineBreakStrategy swimlaneWrapTitleWidth();
public boolean strictUmlStyle(); public boolean strictUmlStyle();

View File

@ -59,8 +59,6 @@ public interface ISkinSimple extends SpriteContainer {
public int getDpi(); public int getDpi();
public LineBreakStrategy wrapWidth();
public void copyAllFrom(Map<String, String> other); public void copyAllFrom(Map<String, String> other);
public SheetBuilder sheet(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, public SheetBuilder sheet(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,

View File

@ -81,6 +81,7 @@ import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleLoader; import net.sourceforge.plantuml.style.StyleLoader;
import net.sourceforge.plantuml.style.parser.StyleParser; 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.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.PackageStyle;
@ -111,6 +112,8 @@ public class SkinParam implements ISkinParam {
if (styleBuilder == null) if (styleBuilder == null)
try { try {
this.styleBuilder = getCurrentStyleBuilderInternal(); this.styleBuilder = getCurrentStyleBuilderInternal();
} catch (StyleParsingException e) {
Logme.error(e);
} catch (IOException e) { } catch (IOException e) {
Logme.error(e); Logme.error(e);
} }
@ -133,7 +136,7 @@ public class SkinParam implements ISkinParam {
this.skin = newSkin; this.skin = newSkin;
} }
public StyleBuilder getCurrentStyleBuilderInternal() throws IOException { public StyleBuilder getCurrentStyleBuilderInternal() throws IOException, StyleParsingException {
final StyleLoader tmp = new StyleLoader(this); final StyleLoader tmp = new StyleLoader(this);
StyleBuilder result = tmp.loadSkin(this.getDefaultSkin()); StyleBuilder result = tmp.loadSkin(this.getDefaultSkin());
if (result == null) if (result == null)
@ -183,6 +186,8 @@ public class SkinParam implements ISkinParam {
for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder)) for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder))
this.muteStyle(modifiedStyle); this.muteStyle(modifiedStyle);
} catch (StyleParsingException e) {
Logme.error(e);
} catch (IOException e) { } catch (IOException e) {
Logme.error(e); Logme.error(e);
} }
@ -894,12 +899,6 @@ public class SkinParam implements ISkinParam {
return new LineBreakStrategy(value); return new LineBreakStrategy(value);
} }
@Override
public LineBreakStrategy wrapWidth() {
final String value = getValue("wrapwidth");
return new LineBreakStrategy(value);
}
@Override @Override
public LineBreakStrategy swimlaneWrapTitleWidth() { public LineBreakStrategy swimlaneWrapTitleWidth() {
final String value = getValue("swimlanewraptitlewidth"); final String value = getValue("swimlanewraptitlewidth");

View File

@ -187,11 +187,6 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.maxMessageSize(); return skinParam.maxMessageSize();
} }
@Override
public LineBreakStrategy wrapWidth() {
return skinParam.wrapWidth();
}
@Override @Override
public boolean strictUmlStyle() { public boolean strictUmlStyle() {
return skinParam.strictUmlStyle(); return skinParam.strictUmlStyle();

View File

@ -90,11 +90,6 @@ public class SpriteContainerEmpty implements SpriteContainer, ISkinSimple {
return 96; return 96;
} }
@Override
public LineBreakStrategy wrapWidth() {
return LineBreakStrategy.NONE;
}
@Override @Override
public void copyAllFrom(Map<String, String> other) { public void copyAllFrom(Map<String, String> other) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -50,6 +50,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandCase;
import net.sourceforge.plantuml.activitydiagram3.command.CommandCircleSpot3; import net.sourceforge.plantuml.activitydiagram3.command.CommandCircleSpot3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElse3; import net.sourceforge.plantuml.activitydiagram3.command.CommandElse3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElseIf2; 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.CommandElseLegacy1;
import net.sourceforge.plantuml.activitydiagram3.command.CommandEnd3; import net.sourceforge.plantuml.activitydiagram3.command.CommandEnd3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandEndPartition3; import net.sourceforge.plantuml.activitydiagram3.command.CommandEndPartition3;
@ -111,6 +112,7 @@ public class ActivityDiagramFactory3 extends PSystemCommandFactory {
cmds.add(new CommandIf2()); cmds.add(new CommandIf2());
cmds.add(CommandDecoratorMultine.create(new CommandIf2(), 50)); cmds.add(CommandDecoratorMultine.create(new CommandIf2(), 50));
cmds.add(new CommandIfLegacy1()); cmds.add(new CommandIfLegacy1());
cmds.add(new CommandElseIf3());
cmds.add(new CommandElseIf2()); cmds.add(new CommandElseIf2());
cmds.add(new CommandElse3()); cmds.add(new CommandElse3());
cmds.add(CommandDecoratorMultine.create(new CommandElse3(), 50)); cmds.add(CommandDecoratorMultine.create(new CommandElse3(), 50));

View File

@ -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<ActivityDiagram3> {
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);
}
}

View File

@ -266,7 +266,7 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock, Styleable
private LineBreakStrategy getWrap() { private LineBreakStrategy getWrap() {
LineBreakStrategy wrap = skinParam.swimlaneWrapTitleWidth(); LineBreakStrategy wrap = skinParam.swimlaneWrapTitleWidth();
if (wrap == LineBreakStrategy.NONE) if (wrap == LineBreakStrategy.NONE)
wrap = skinParam.wrapWidth(); wrap = style.wrapWidth();
return wrap; return wrap;
} }

View File

@ -97,6 +97,4 @@ public class FtileFactoryDelegatorAssembly extends FtileFactoryDelegator {
return result; return result;
} }
private final Rose rose = new Rose();
} }

View File

@ -105,8 +105,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
public Quark currentQuark() { public Quark currentQuark() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public /*protected*/ Plasma getPlasma() { public /* protected */ Plasma getPlasma() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -305,13 +305,27 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return Collections.unmodifiableCollection(result); return Collections.unmodifiableCollection(result);
} }
final public void gotoGroup(Ident ident, Code code, Display display, GroupType type, IGroup parent, private NamespaceStrategy lastNamespaceStrategy;
NamespaceStrategy strategy) {
if (this.V1972()) { final public CommandExecutionResult gotoGroup(Ident ident, Code code, Display display, GroupType type,
gotoGroupInternalWithNamespace(ident, code, display, code, type, parent); IGroup parent, NamespaceStrategy strategy) {
return; 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 (strategy == NamespaceStrategy.MULTIPLE) {
if (getNamespaceSeparator() != null) if (getNamespaceSeparator() != null)
code = getFullyQualifiedCode1972(code); code = getFullyQualifiedCode1972(code);
@ -324,6 +338,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
} else { } else {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
return CommandExecutionResult.ok();
} }
protected final String getNamespace1972(Code fullyCode, String separator) { protected final String getNamespace1972(Code fullyCode, String separator) {
@ -373,6 +388,12 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
} }
public void endGroup() { public void endGroup() {
if (currentGroup.getGroupType() == GroupType.TOGETHER) {
currentGroup = currentGroup.getParentContainer();
return;
}
if (stacks2.size() > 0) { if (stacks2.size() > 0) {
// Thread.dumpStack(); // Thread.dumpStack();
stacks2.remove(stacks2.size() - 1); stacks2.remove(stacks2.size() - 1);
@ -672,6 +693,9 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
} }
public boolean isAutarkic(IGroup g) { public boolean isAutarkic(IGroup g) {
if (g.getGroupType() == GroupType.TOGETHER)
return false;
if (g.getGroupType() == GroupType.PACKAGE) if (g.getGroupType() == GroupType.PACKAGE)
return false; return false;

View File

@ -131,7 +131,8 @@ public final class EntityFactory implements IEntityFactory {
final Collection<IGroup> children = parent.getChildren(); final Collection<IGroup> children = parent.getChildren();
if (leafs == 0 && children.size() == 1) { if (leafs == 0 && children.size() == 1) {
final IGroup g = children.iterator().next(); 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; return null;
for (Link link : this.getLinks()) for (Link link : this.getLinks())
@ -192,20 +193,24 @@ public final class EntityFactory implements IEntityFactory {
return result; return result;
} }
private IEntity isNoteWithSingleLinkAttachedTo(ILeaf leaf) { private IEntity isNoteWithSingleLinkAttachedTo(ILeaf note) {
if (leaf.getLeafType() != LeafType.NOTE) if (note.getLeafType() != LeafType.NOTE)
return null; return null;
IEntity result = null; assert note.getLeafType() == LeafType.NOTE;
IEntity other = null;
for (Link link : this.getLinks()) { for (Link link : this.getLinks()) {
if (link.getType().isInvisible()) if (link.getType().isInvisible())
continue; continue;
if (link.contains(leaf)) { if (link.contains(note) == false)
if (result != null) continue;
return result; if (other != null)
result = link.getOther(leaf); return null;
} other = link.getOther(note);
if (other.getLeafType() == LeafType.NOTE)
return null;
} }
return result; return other;
} }

View File

@ -171,8 +171,8 @@ final public class EntityImp implements ILeaf, IGroup {
this.rawLayout = rawLayout; this.rawLayout = rawLayout;
} }
public EntityImp(Ident ident, Code code, EntityFactory entityFactory, Bodier bodier, public EntityImp(Ident ident, Code code, EntityFactory entityFactory, Bodier bodier, IGroup parentContainer,
IGroup parentContainer, LeafType leafType, String namespaceSeparator, int rawLayout) { LeafType leafType, String namespaceSeparator, int rawLayout) {
this(Objects.requireNonNull(ident), entityFactory, code, bodier, parentContainer, namespaceSeparator, this(Objects.requireNonNull(ident), entityFactory, code, bodier, parentContainer, namespaceSeparator,
rawLayout); rawLayout);
// System.err.println("ID for leaf=" + code + " " + ident); // System.err.println("ID for leaf=" + code + " " + ident);
@ -782,6 +782,7 @@ final public class EntityImp implements ILeaf, IGroup {
public void setThisIsTogether() { public void setThisIsTogether() {
this.together = true; this.together = true;
setUSymbol(USymbols.TOGETHER);
} }
public String getCodeLine() { public String getCodeLine() {

View File

@ -76,6 +76,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementMultilin
import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementParenthesis; import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementParenthesis;
import net.sourceforge.plantuml.descdiagram.command.CommandNewpage; import net.sourceforge.plantuml.descdiagram.command.CommandNewpage;
import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; 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.CommandCreateEntityObject;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson;
@ -118,6 +119,7 @@ public class ClassDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandEndPackage()); cmds.add(new CommandEndPackage());
cmds.add(new CommandPackageEmpty()); cmds.add(new CommandPackageEmpty());
cmds.add(new CommandPackageWithUSymbol()); cmds.add(new CommandPackageWithUSymbol());
cmds.add(new CommandTogether());
cmds.add(new CommandCreateElementFull2(Mode.NORMAL_KEYWORD)); cmds.add(new CommandCreateElementFull2(Mode.NORMAL_KEYWORD));
cmds.add(new CommandCreateElementFull2(Mode.WITH_MIX_PREFIX)); cmds.add(new CommandCreateElementFull2(Mode.WITH_MIX_PREFIX));

View File

@ -106,12 +106,14 @@ public class CommandNamespace extends SingleLineCommand2<ClassDiagram> {
currentPackage = diagram.getCurrentGroup(); currentPackage = diagram.getCurrentGroup();
display = Display.getWithNewlines(code); 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 IEntity p = diagram.getCurrentGroup();
final String stereotype = arg.get("STEREOTYPE", 0); final String stereotype = arg.get("STEREOTYPE", 0);
if (stereotype != null) { if (stereotype != null)
p.setStereotype(Stereotype.build(stereotype)); p.setStereotype(Stereotype.build(stereotype));
}
final String urlString = arg.get("URL", 0); final String urlString = arg.get("URL", 0);
if (urlString != null) { if (urlString != null) {
@ -121,9 +123,9 @@ public class CommandNamespace extends SingleLineCommand2<ClassDiagram> {
} }
final String color = arg.get("COLOR", 0); final String color = arg.get("COLOR", 0);
if (color != null) { if (color != null)
p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color)); p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color));
}
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -94,12 +94,14 @@ public class CommandNamespace2 extends SingleLineCommand2<ClassDiagram> {
final IGroup currentPackage = diagram.getCurrentGroup(); final IGroup currentPackage = diagram.getCurrentGroup();
final String disp = arg.getLazzy("DISPLAY", 0); final String disp = arg.getLazzy("DISPLAY", 0);
final Display display = Display.getWithNewlines(disp); 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 IEntity p = diagram.getCurrentGroup();
final String stereotype = arg.get("STEREOTYPE", 0); final String stereotype = arg.get("STEREOTYPE", 0);
if (stereotype != null) { if (stereotype != null)
p.setStereotype(Stereotype.build(stereotype)); p.setStereotype(Stereotype.build(stereotype));
}
final String urlString = arg.get("URL", 0); final String urlString = arg.get("URL", 0);
if (urlString != null) { if (urlString != null) {
@ -109,9 +111,9 @@ public class CommandNamespace2 extends SingleLineCommand2<ClassDiagram> {
} }
final String color = arg.get("COLOR", 0); final String color = arg.get("COLOR", 0);
if (color != null) { if (color != null)
p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color)); p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color));
}
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -88,12 +88,14 @@ public class CommandNamespaceEmpty extends SingleLineCommand2<ClassDiagram> {
final Code code = diagram.V1972() ? idNewLong : diagram.buildCode(idShort); final Code code = diagram.V1972() ? idNewLong : diagram.buildCode(idShort);
final IGroup currentPackage = diagram.getCurrentGroup(); final IGroup currentPackage = diagram.getCurrentGroup();
final Display display = Display.getWithNewlines(code); 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 IEntity p = diagram.getCurrentGroup();
final String stereotype = arg.get("STEREOTYPE", 0); final String stereotype = arg.get("STEREOTYPE", 0);
if (stereotype != null) { if (stereotype != null)
p.setStereotype(Stereotype.build(stereotype)); p.setStereotype(Stereotype.build(stereotype));
}
final String urlString = arg.get("URL", 0); final String urlString = arg.get("URL", 0);
if (urlString != null) { if (urlString != null) {
@ -103,9 +105,9 @@ public class CommandNamespaceEmpty extends SingleLineCommand2<ClassDiagram> {
} }
final String color = arg.get("COLOR", 0); final String color = arg.get("COLOR", 0);
if (color != null) { if (color != null)
p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color)); p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color));
}
diagram.endGroup(); diagram.endGroup();
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -128,7 +128,7 @@ public class CommandPackage extends SingleLineCommand2<AbstractEntityDiagram> {
final Ident ident; final Ident ident;
final Code code; final Code code;
if (CucaDiagram.QUARK) { if (CucaDiagram.QUARK) {
final Quark current = diagram.currentQuark(); final Quark current = diagram.currentQuark();
code = current; code = current;
@ -140,9 +140,10 @@ public class CommandPackage extends SingleLineCommand2<AbstractEntityDiagram> {
display = ident.getLast(); display = ident.getLast();
} }
final IGroup currentPackage = diagram.getCurrentGroup(); final IGroup currentPackage = diagram.getCurrentGroup();
final CommandExecutionResult status = diagram.gotoGroup(ident, code, Display.getWithNewlines(display),
diagram.gotoGroup(ident, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, GroupType.PACKAGE, currentPackage, NamespaceStrategy.SINGLE);
NamespaceStrategy.SINGLE); if (status.isOk() == false)
return status;
final IEntity p = diagram.getCurrentGroup(); final IEntity p = diagram.getCurrentGroup();

View File

@ -100,14 +100,15 @@ public class CommandPackageEmpty extends SingleLineCommand2<AbstractEntityDiagra
final IGroup currentPackage = diagram.getCurrentGroup(); final IGroup currentPackage = diagram.getCurrentGroup();
final Ident ident = diagram.buildLeafIdent(idShort); final Ident ident = diagram.buildLeafIdent(idShort);
final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort);
diagram.gotoGroup(ident, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, final CommandExecutionResult status = diagram.gotoGroup(ident, code, Display.getWithNewlines(display),
NamespaceStrategy.SINGLE); GroupType.PACKAGE, currentPackage, NamespaceStrategy.SINGLE);
if (status.isOk() == false)
return status;
final IEntity p = diagram.getCurrentGroup(); final IEntity p = diagram.getCurrentGroup();
final String color = arg.get("COLOR", 0); final String color = arg.get("COLOR", 0);
if (color != null) { if (color != null)
p.setSpecificColorTOBEREMOVED(ColorType.BACK, p.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColor(color));
diagram.getSkinParam().getIHtmlColorSet().getColor(color));
}
diagram.endGroup(); diagram.endGroup();
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -78,13 +78,12 @@ public class CommandCreatePackageBlock extends SingleLineCommand2<CompositeDiagr
String display = arg.get("DISPLAY", 0); String display = arg.get("DISPLAY", 0);
final String idShort = arg.get("CODE", 0); final String idShort = arg.get("CODE", 0);
final Code code = diagram.buildCode(idShort); final Code code = diagram.buildCode(idShort);
if (display == null) { if (display == null)
display = code.getName(); display = code.getName();
}
final Ident idNewLong = diagram.buildLeafIdent(idShort); final Ident idNewLong = diagram.buildLeafIdent(idShort);
diagram.gotoGroup(idNewLong, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, return diagram.gotoGroup(idNewLong, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage,
NamespaceStrategy.SINGLE); NamespaceStrategy.SINGLE);
return CommandExecutionResult.ok();
} }
} }

View File

@ -513,11 +513,6 @@ public class Display implements Iterable<CharSequence> {
return create7(fontConfiguration, horizontalAlignment, spriteContainer, CreoleMode.FULL); 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, public TextBlock create7(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple spriteContainer, CreoleMode creoleMode) { ISkinSimple spriteContainer, CreoleMode creoleMode) {
return create0(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode, return create0(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode,

View File

@ -37,6 +37,6 @@ package net.sourceforge.plantuml.cucadiagram;
public enum GroupType { public enum GroupType {
PACKAGE, STATE, CONCURRENT_STATE, INNER_ACTIVITY, CONCURRENT_ACTIVITY, DOMAIN, REQUIREMENT PACKAGE, TOGETHER, STATE, CONCURRENT_STATE, INNER_ACTIVITY, CONCURRENT_ACTIVITY, DOMAIN, REQUIREMENT
} }

View File

@ -242,7 +242,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlock,
config = config.underline(); config = config.underline();
TextBlock bloc = Display.getWithNewlines(s).create8(config, align, skinParam, CreoleMode.SIMPLE_LINE, TextBlock bloc = Display.getWithNewlines(s).create8(config, align, skinParam, CreoleMode.SIMPLE_LINE,
skinParam.wrapWidth()); style.wrapWidth());
bloc = TextBlockUtils.fullInnerPosition(bloc, m.getDisplay(false)); bloc = TextBlockUtils.fullInnerPosition(bloc, m.getDisplay(false));
return new TextBlockTracer(m, bloc); return new TextBlockTracer(m, bloc);
} }
@ -251,7 +251,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlock,
// return ((EmbeddedDiagram) cs).asDraw(skinParam); // return ((EmbeddedDiagram) cs).asDraw(skinParam);
return Display.getWithNewlines(cs.toString()).create8(config, align, skinParam, CreoleMode.SIMPLE_LINE, return Display.getWithNewlines(cs.toString()).create8(config, align, skinParam, CreoleMode.SIMPLE_LINE,
skinParam.wrapWidth()); style.wrapWidth());
} }

View File

@ -61,6 +61,7 @@ import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementMultilin
import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement;
import net.sourceforge.plantuml.descdiagram.command.CommandNewpage; import net.sourceforge.plantuml.descdiagram.command.CommandNewpage;
import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol; 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.CommandCreateJson;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJsonSingleLine;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap; import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap;
@ -83,8 +84,10 @@ public class DescriptionDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandLinkElement()); cmds.add(new CommandLinkElement());
cmds.add(new CommandHideShow2()); cmds.add(new CommandHideShow2());
cmds.add(new CommandRemoveRestore()); cmds.add(new CommandRemoveRestore());
//
cmds.add(new CommandPackageWithUSymbol()); cmds.add(new CommandPackageWithUSymbol());
cmds.add(new CommandTogether());
cmds.add(new CommandEndPackage()); cmds.add(new CommandEndPackage());
final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote(); final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote();
cmds.add(factoryNoteCommand.createMultiLine(false)); cmds.add(factoryNoteCommand.createMultiLine(false));

View File

@ -74,7 +74,7 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2<AbstractEntity
private static IRegex getRegexConcat() { private static IRegex getRegexConcat() {
return RegexConcat.build(CommandPackageWithUSymbol.class.getName(), RegexLeaf.start(), // return RegexConcat.build(CommandPackageWithUSymbol.class.getName(), RegexLeaf.start(), //
new RegexLeaf("SYMBOL", new RegexLeaf("SYMBOL",
"(package|rectangle|hexagon|node|artifact|folder|file|frame|cloud|database|storage|component|card|together|queue|stack)"), // "(package|rectangle|hexagon|node|artifact|folder|file|frame|cloud|database|storage|component|card|queue|stack)"), //
RegexLeaf.spaceOneOrMore(), // RegexLeaf.spaceOneOrMore(), //
new RegexOr(// new RegexOr(//
new RegexConcat( // new RegexConcat( //
@ -156,12 +156,12 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2<AbstractEntity
final Ident ident = diagram.buildLeafIdent(idShort); final Ident ident = diagram.buildLeafIdent(idShort);
final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort);
final IGroup currentPackage = diagram.getCurrentGroup(); final IGroup currentPackage = diagram.getCurrentGroup();
diagram.gotoGroup(ident, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, final CommandExecutionResult status = diagram.gotoGroup(ident, code, Display.getWithNewlines(display),
NamespaceStrategy.SINGLE); GroupType.PACKAGE, currentPackage, NamespaceStrategy.SINGLE);
if (status.isOk() == false)
return status;
final IEntity p = diagram.getCurrentGroup(); final IEntity p = diagram.getCurrentGroup();
final String symbol = arg.get("SYMBOL", 0); final String symbol = arg.get("SYMBOL", 0);
if ("together".equalsIgnoreCase(symbol))
p.setThisIsTogether();
p.setUSymbol(USymbols.fromString(symbol, diagram.getSkinParam().actorStyle(), p.setUSymbol(USymbols.fromString(symbol, diagram.getSkinParam().actorStyle(),
diagram.getSkinParam().componentStyle(), diagram.getSkinParam().packageStyle())); diagram.getSkinParam().componentStyle(), diagram.getSkinParam().packageStyle()));

View File

@ -0,0 +1,85 @@
/* ========================================================================
* 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.descdiagram.command;
import net.sourceforge.plantuml.baraye.IEntity;
import net.sourceforge.plantuml.baraye.IGroup;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
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.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Code;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.GroupType;
import net.sourceforge.plantuml.cucadiagram.Ident;
import net.sourceforge.plantuml.cucadiagram.NamespaceStrategy;
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
import net.sourceforge.plantuml.utils.LineLocation;
public class CommandTogether extends SingleLineCommand2<AbstractEntityDiagram> {
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();
}
}

View File

@ -71,31 +71,30 @@ public class PSystemDonors extends PlainDiagram {
private static final int COLS = 6; private static final int COLS = 6;
private static final int FREE_LINES = 6; private static final int FREE_LINES = 6;
public static final String DONORS = "6miF03mSRygAr4-2sU91UhPs3uiVqvmG9uBbUK9nOX6dku3u0zmxFUutqbz4LtRlcsP4hTScvGoY-Y3e" public static final String DONORS = "6r8F0AoFktsyGOBPua5wjfPR-fZcX3WHBCyJYiF0HZpT1SGVuDxfSR-H_YAwqhrlcZ5glPofDGbvnfSS"
+ "0Uzk2-r3wNzz4EOiUH7ScH9SG0g8ukWI-P5kP3jzKcL82TvyX-vlcQmzsJek5ZMV4u6h02gHaD6SOhkN" + "iFHQuIQCt_d2eyvUFWIVD0A61iW0SLF_nZdioMcw8rM6bE3DT-Z-bidQawtZOb7pEH6u2g0IqPnYkvU9"
+ "YNczGYgb-FoLZz1Fu6tww3nt6aMZ_XEuUTJsKUnzpVzDdMNdeH1cwMu5Hc1KD49rth77-FyKGOKes3bK" + "URr2AgNu_9MFq4yWcuBESwPH96fUuEQexQVO-vhxdpexbp1BToim0gEY4QhylkPOUxarxw9QL8c2dQ0A"
+ "mOubntGghLeELNICUL_N0dLCkbPDauygDQjYN5MaM4Od3Oj89jJbOl8nyg9F6h_Kc_3XkYeauzu1dMrr" + "TepbL5gr7AgeZ2tBoCS-CD6QGpwgrAoACHUHOXYTD0mY4QZBnUXZvCMOL7wfD-73TLL8Hjq1dMqDT7tJ"
+ "T7tJspRFnFppHH-2ZC4t53Km0jOZQHFDpqCF6aOE66fsuSOM5OuyYOT46hIGN_vGc48loTaLSDCmgG24" + "sZRFnFJpHH-XqWRVOAJ025YEn4sqV1v6KD5oG52pYsniKUN8apXGf48B_kKFXQcCafnT0JKLdGP067m7"
+ "nJjGWIG7rQdXRCTXG8KbjcYpyAYB_S7Ik2uhfp9TQNWYiJ4nKGkeKkH_q0tTKUjuD7NtC3WYFIKQOSjH" + "AeXafperd6qw3AYmn1Pj5guwrzzO6k_BybIc2mrF83Ow9bg1LOBy3xh1EsiTZqIrXq4HwIdH6BOSvNCe"
+ "FWjifHrMzFbPIWGBWCwOnVehH3cLr7GSpzg_Soq0kwNbLGzZ2dzEe2bBA9JnYGNgLw7Rve8jUkzoi906" + "M-c75NrkrX910g1Jit1_-IYdahgEurdxTwu5uB2qVDV37CET4sZA4gh8-6X1nXNehBKWYzwx72oaGDZ7"
+ "KH-7R_g8S-MXkWX7P4fPhQENiPrhcJzqsOBrINWABEGzxakn1HniYgigDO0lj0ffgVC992tpxwN7ot_V" + "uPinTAuyj2p2DfvI5clxPMnxBVE7hhJ1-iGy1HR-FVPBhWKSQj9LaXR05rg5TEjyef2M-VVIuzj_tnEk"
+ "4wufb6IlNxGHhf3qquznCaCXGFkcCHkwYGABiIfMhSKMHB17wT00hOLa4CwHTjb7_99-vIS0tbn2T9kD" + "AUIurotw25T8-kt7sCnO2D2-PKX3Dq4W2TobLMkn1H7g4TetG6iX6OHpf5ts4R-aZ_m4m5kM4CDX4qez"
+ "G3tuzvUc31svI0C9NPN62c3rQKNTDCmUmQ1KKz7rHCMNtiQFhqnhx6EbiMfPjCdpHeCnyfjqcc9ZkK95" + "-FDBKQQENAW93rsLnWfWQR6YRIfwZs1GgYdeObHnPRJnuolJEljODfOiYpvvNcem9dvDfoWsbYjKP8PX"
+ "XXaMwc7DcU_KbcYNucxfWrUz9tjT1RYKUG-vSUyN6V1p3nce59pkUCz7Rbc62OjPF7EzJEcPdqnk7hhn" + "eHxHdFcsjfLs2MwNCNZLVM9b5T1QuJtanhrVP22VUyX49EyCnti-SiioJKZCufZhPKhF-cHoyz2D2yxi"
+ "m5qiciQCClMGPS1WVoAgzP6eRnOZl-sGpSXh9Re7iBuA90SFCoh1woScLrHpJCDeaqLqR14YsToyufHT" + "fYSpofH3bW6TtSberaUiiLbCVpF8PkIridWCO7mDHLlmCACOl7uqEQQQOofQcooYOeiGITRc5RkOS1P1"
+ "kRPWCozFagEYHChDLWz3Gdv7-YAYLT96gSFcV9VW6PAZ82_dtR7gCN-xOUe2AbCdWKzQi6PBQD-pBf21" + "dfOZoL5HGkKMgriX8RzjOn6HAd6Zr65pkZFm3EzHb9VppbdrcB_TIie2AbERm2KjIAkbOj-pBf2XUoSz"
+ "jOkUgPR4wVy-iI3lVJampL1y9Oas7jn0CGLcXd0V65WY6SXAnKkR617ulZ_kZXxnEjJZRvzECGwIRf8O" + "Kos9C_vzOi6sz-M1mQ7qYecM7jm0c4AIBZ8F128HEWgbz58cXWM-xhUxrUDp7TBnjq-d68T83qa2L073"
+ "g8A4arzGJTHPHuGJwpN-_wPFIrpuywyzRPDJlJtx7e9eCuWBG9WNw8gS5q8y1RusDam1dC8I5vqaNBbi" + "sLvGZTJPHeIDzHh_VzEd9Ixy-TUwRPDJlRtttONGE4WMW0WlDAIS4q8y1JutDam6dCAIB3f9k7BMqek1"
+ "xPL0b8ADzC4kwlPbHld6JvORaPlMNZzKuKzJZ0h7_K2s2r_HtkUIAjCNqwW6-yEx3XSv6FubgWo8vB8t" + "o8ADZC4kwcoPqNRZ9ykDo4rlBn-gyAUhN5JOwGTqNBXIx7qkgJ9zCOEAsRxnZSL53W7_4bL6PNBlAgDP"
+ "CoiZKIR1nN4VfxKDpLWwG0tcG9q4djtzsMAXeR7sAvGgmmcGhpSabHfbMbWTqzBO2AoK4_jxQqxA6VNP" + "OIJYA6HnxCVfRKFJ5pf8mHgeJU3OtUyj5XgQQxyYgJGSW7oo8QdKhD2YQarBOoEmKaxixwquAMVMPsUY"
+ "6SJF7klCULKFTPCKrrECA7o7ISXJmiJC8d4YWjtYEIb13z_i8rzK2oMnjAdDpX2iaF--7yCR2GVia0SQ" + "7zCwSrxLGzqaPzTJZ2Xy-oaqzmWJqqNSX8LmJyv934Rune9yKIsMnDAo3ZjDi8B_-tuCRoHiieCF5Ee9"
+ "zOHIdcb13jkaUziiy4U2zn0ba8N5Cjr5B9JAU215KZ2NMyOpfA-q6QVs1j0f2iR_zmQKoqmqFwBPfNTr" + "fJpJWXnXa-nzgoZ-8DvTn40M5ijq9x5Ool58YgHmhcoPd25zfKyufMyGWw9m_7ylGRZCHFCLaYwzgvFC"
+ "ahd2rdRY82h3_PubjYZPQf61VLVDPUkNvRRDJMROaV-17plV_AYwVX41DKHN9NZDQUJ3ZSrgQjYY_cOE" + "vRTMamoYEDJF9Ab5obQB3EoRIovRl2AtRMtIOTl-1txYVFaZwkAR220GpONWDQUX3pVMgwbX2_ARETp7"
+ "zt6PhPl9p-DIj7DK0vlqPAE6iXaev2I4I0T2XVHL-5Nz2LlEEVBfVQeK1cfu7hiDFNYk1kR8LXfU9Gse" + "PRPk9Z-FIz7EKGbirYSRDS1cgE991647e49u3VrL_GbRpcNus_DKAepKyDnH3JruhWQMaQqql4WQrBp8"
+ "NcHnR7s_uIPF3XHEJBR-LQUnqyEO7gqmrAQRDcl8e1AvIyLNZc1sSqcLjoecbJAyy-FUKBCajFQTxUZq" + "OjhwVifDdXn8d00TKAawZPqUneneXKCjlscp98DAuauL_ti6qjqbLTwgc3JAaAXwWysIs3hlpD3fdDmg"
+ "JcuXbzTpFBqnWqlzakWpmJa6ch9U7CY41cGHMK4ZYAwI_Q8LPyYeBAl4HwfWc3ZQ4kxGQ3DOk3lMfw5i" + "N5xFyVJ632dr2-eBWZs6kbpF3NW20meXhW05oLNpljMACsHKbbNZmoeKHWws5JKqsWmMsHtZqr0shvYj"
+ "NZ5RuziaFZ126vR-nWNSUuP4pmKD8zkS06nO52cKX6OetMCGEs57p2vkUISVW_BMtW00"; + "yUpO5i08L0pzWmjxZuP6JgXesUQ4CXiH1ObIQ0ieiySejc6VaYvkEJMTj_PENUY7pPDDDVeMbUB0EZoZ" + "yWe1";
/* /*
* Special thanks to our sponsors and donors: * Special thanks to our sponsors and donors:
* *

View File

@ -99,7 +99,7 @@ public class EbnfExpression implements TextBlockable {
tokens.add(new Token(Symbol.REPETITION_OPEN, null)); tokens.add(new Token(Symbol.REPETITION_OPEN, null));
} else if (ch == '}' && it.peek(1) == '-') { } else if (ch == '}' && it.peek(1) == '-') {
tokens.add(new Token(Symbol.REPETITION_MINUS_CLOSE, null)); tokens.add(new Token(Symbol.REPETITION_MINUS_CLOSE, null));
it.next(); it.jump();
} else if (ch == '}') { } else if (ch == '}') {
tokens.add(new Token(Symbol.REPETITION_CLOSE, null)); tokens.add(new Token(Symbol.REPETITION_CLOSE, null));
} else if (ch == ';' || ch == 0) { } else if (ch == ';' || ch == 0) {
@ -118,7 +118,7 @@ public class EbnfExpression implements TextBlockable {
tokens.clear(); tokens.clear();
return; return;
} }
it.next(); it.jump();
continue; continue;
} }
} }
@ -213,14 +213,14 @@ public class EbnfExpression implements TextBlockable {
private String readString(CharInspector it) { private String readString(CharInspector it) {
final char separator = it.peek(0); final char separator = it.peek(0);
it.next(); it.jump();
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
while (true) { while (true) {
final char ch = it.peek(0); final char ch = it.peek(0);
if (ch == separator) if (ch == separator)
return sb.toString(); return sb.toString();
sb.append(ch); sb.append(ch);
it.next(); it.jump();
} }
} }
@ -231,25 +231,25 @@ public class EbnfExpression implements TextBlockable {
if (isLetterOrDigit(ch) == false) if (isLetterOrDigit(ch) == false)
return sb.toString(); return sb.toString();
sb.append(ch); sb.append(ch);
it.next(); it.jump();
} }
} }
private String readComment(CharInspector it) { private String readComment(CharInspector it) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
it.next(); it.jump();
it.next(); it.jump();
while (true) { while (true) {
final char ch = it.peek(0); final char ch = it.peek(0);
if (ch == '\0') if (ch == '\0')
return sb.toString(); return sb.toString();
if (ch == '*' && it.peek(1) == ')') { if (ch == '*' && it.peek(1) == ')') {
it.next(); it.jump();
it.next(); it.jump();
return sb.toString(); return sb.toString();
} }
sb.append(ch); sb.append(ch);
it.next(); it.jump();
} }
} }

View File

@ -45,9 +45,9 @@ public class EggUtils {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
for (byte b : data) { for (byte b : data) {
final String hex = Integer.toHexString(b & 0xFF); final String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) { if (hex.length() == 1)
sb.append('0'); sb.append('0');
}
sb.append(hex); sb.append(hex);
} }
return sb.toString(); return sb.toString();
@ -55,9 +55,9 @@ public class EggUtils {
public static byte[] toByteArrays(String s) { public static byte[] toByteArrays(String s) {
final byte[] result = new byte[s.length() / 2]; 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); result[i] = (byte) Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16);
}
return result; return result;
} }
@ -71,7 +71,6 @@ public class EggUtils {
if (num != -1) { if (num != -1) {
result = result.multiply(twentySix); result = result.multiply(twentySix);
result = result.add(BigInteger.valueOf(num)); result = result.add(BigInteger.valueOf(num));
} }
} }
return result; return result;
@ -80,9 +79,8 @@ public class EggUtils {
private static int convertChar(char c) { private static int convertChar(char c) {
c = StringUtils.goLowerCase(c); c = StringUtils.goLowerCase(c);
if (c >= 'a' && c <= 'z') { if (c >= 'a' && c <= 'z')
return c - 'a'; return c - 'a';
}
return -1; return -1;
} }
@ -91,10 +89,8 @@ public class EggUtils {
int pos = 0; int pos = 0;
for (int i = 0; i < result.length; i++) { for (int i = 0; i < result.length; i++) {
result[i] = (byte) (data[i] ^ key[pos++]); result[i] = (byte) (data[i] ^ key[pos++]);
if (pos == key.length) { if (pos == key.length)
pos = 0; pos = 0;
}
} }
return result; return result;
} }

View File

@ -49,6 +49,7 @@ import net.sourceforge.plantuml.json.JsonValue;
import net.sourceforge.plantuml.jsondiagram.JsonDiagram; import net.sourceforge.plantuml.jsondiagram.JsonDiagram;
import net.sourceforge.plantuml.jsondiagram.StyleExtractor; import net.sourceforge.plantuml.jsondiagram.StyleExtractor;
import net.sourceforge.plantuml.log.Logme; import net.sourceforge.plantuml.log.Logme;
import net.sourceforge.plantuml.yaml.Highlighted;
public class HclDiagramFactory extends PSystemAbstractFactory { public class HclDiagramFactory extends PSystemAbstractFactory {
@ -58,7 +59,7 @@ public class HclDiagramFactory extends PSystemAbstractFactory {
@Override @Override
public Diagram createSystem(UmlSource source, Map<String, String> skinParam) { public Diagram createSystem(UmlSource source, Map<String, String> skinParam) {
final List<String> highlighted = new ArrayList<>(); final List<Highlighted> highlighted = new ArrayList<>();
JsonValue data = null; JsonValue data = null;
StyleExtractor styleExtractor = null; StyleExtractor styleExtractor = null;
try { try {

View File

@ -62,14 +62,15 @@ import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.hand.UGraphicHandwritten; import net.sourceforge.plantuml.ugraphic.hand.UGraphicHandwritten;
import net.sourceforge.plantuml.yaml.Highlighted;
public class JsonDiagram extends TitledDiagram { public class JsonDiagram extends TitledDiagram {
private final JsonValue root; private final JsonValue root;
private final List<String> highlighted; private final List<Highlighted> highlighted;
private final boolean handwritten; private final boolean handwritten;
public JsonDiagram(UmlSource source, UmlDiagramType type, JsonValue json, List<String> highlighted, public JsonDiagram(UmlSource source, UmlDiagramType type, JsonValue json, List<Highlighted> highlighted,
StyleExtractor styleExtractor) { StyleExtractor styleExtractor) {
super(source, type, null); super(source, type, null);
this.handwritten = styleExtractor.isHandwritten(); this.handwritten = styleExtractor.isHandwritten();

View File

@ -49,6 +49,9 @@ import net.sourceforge.plantuml.core.UmlSource;
import net.sourceforge.plantuml.json.Json; import net.sourceforge.plantuml.json.Json;
import net.sourceforge.plantuml.json.JsonValue; import net.sourceforge.plantuml.json.JsonValue;
import net.sourceforge.plantuml.json.ParseException; 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 { public class JsonDiagramFactory extends PSystemAbstractFactory {
@ -58,7 +61,7 @@ public class JsonDiagramFactory extends PSystemAbstractFactory {
@Override @Override
public Diagram createSystem(UmlSource source, Map<String, String> skinParam) { public Diagram createSystem(UmlSource source, Map<String, String> skinParam) {
final List<String> highlighted = new ArrayList<>(); final List<Highlighted> highlighted = new ArrayList<>();
StyleExtractor styleExtractor = null; StyleExtractor styleExtractor = null;
JsonValue json; JsonValue json;
try { try {
@ -72,8 +75,8 @@ public class JsonDiagramFactory extends PSystemAbstractFactory {
break; break;
if (line.startsWith("#")) { if (line.startsWith("#")) {
if (line.startsWith("#highlight ")) { if (Highlighted.matchesDefinition(line)) {
highlighted.add(line.substring("#highlight ".length()).trim()); highlighted.add(Highlighted.build(line));
continue; continue;
} }
} else { } else {
@ -87,7 +90,11 @@ public class JsonDiagramFactory extends PSystemAbstractFactory {
} }
final JsonDiagram result = new JsonDiagram(source, UmlDiagramType.JSON, json, highlighted, styleExtractor); final JsonDiagram result = new JsonDiagram(source, UmlDiagramType.JSON, json, highlighted, styleExtractor);
if (styleExtractor != null) if (styleExtractor != null)
styleExtractor.applyStyles(result.getSkinParam()); try {
styleExtractor.applyStyles(result.getSkinParam());
} catch (StyleParsingException e) {
Logme.error(e);
}
return result; return result;
} }

View File

@ -63,6 +63,7 @@ import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.yaml.Highlighted;
import smetana.core.CString; import smetana.core.CString;
import smetana.core.Macro; import smetana.core.Macro;
import smetana.core.Z; import smetana.core.Z;
@ -125,24 +126,8 @@ public class SmetanaForJson {
.getMergedStyle(skinParam.getCurrentStyleBuilder()); .getMergedStyle(skinParam.getCurrentStyleBuilder());
} }
private Style getStyleNodeHeader() { private ST_Agnode_s manageOneNode(JsonValue current, List<Highlighted> highlighted) {
return StyleSignatureBasic.of(SName.root, SName.element, getDiagramType(), SName.header, SName.node) final TextBlockJson block = new TextBlockJson(skinParam, current, highlighted);
.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<String> highlighted) {
final TextBlockJson block = new TextBlockJson(skinParam, current, highlighted, getStyleNode(),
getStyleNodeHighlight(), getStyleNodeHeader(), getStyleNodeHeaderHighlight());
final ST_Agnode_s node1 = createNode(block.calculateDimension(stringBounder), block.size(), current.isArray(), final ST_Agnode_s node1 = createNode(block.calculateDimension(stringBounder), block.size(), current.isArray(),
(int) block.getWidthColA(stringBounder), (int) block.getWidthColB(stringBounder)); (int) block.getWidthColA(stringBounder), (int) block.getWidthColB(stringBounder));
nodes.add(new InternalNode(block, node1)); nodes.add(new InternalNode(block, node1));
@ -151,7 +136,7 @@ public class SmetanaForJson {
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
final JsonValue tmp = children.get(i); final JsonValue tmp = children.get(i);
if (tmp != null) { 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); final ST_Agedge_s edge = createEdge(node1, childBloc, i);
edges.add(edge); edges.add(edge);
} }
@ -160,49 +145,41 @@ public class SmetanaForJson {
} }
private List<String> removeOneLevel(String key, List<String> list) { private List<Highlighted> upOneLevel(String key, List<Highlighted> list) {
final List<String> result = new ArrayList<>(); final List<Highlighted> result = new ArrayList<>();
for (String tmp : list) { for (Highlighted tmp : list) {
if (tmp.startsWith("\"" + key + "\"") == false) { final Highlighted parent = tmp.upOneLevel(key);
continue; if (parent != null)
} result.add(parent);
tmp = tmp.trim().replaceFirst("\"([^\"]+)\"", "").trim();
if (tmp.length() > 0) {
tmp = tmp.substring(1).trim();
result.add(tmp);
}
} }
return Collections.unmodifiableList(result); return Collections.unmodifiableList(result);
} }
public void drawMe(JsonValue root, List<String> highlighted) { public void drawMe(JsonValue root, List<Highlighted> highlighted) {
initGraph(root, highlighted); initGraph(root, highlighted);
double max = 0; double max = 0;
for (InternalNode node : nodes) { for (InternalNode node : nodes)
max = Math.max(max, node.getMaxX()); max = Math.max(max, node.getMaxX());
}
xMirror = new Mirror(max); xMirror = new Mirror(max);
for (InternalNode node : nodes) { for (InternalNode node : nodes)
node.block.drawU( node.block.drawU(getStyleNode().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet())
getStyleNode().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()) .apply(getPosition(node.node)));
.apply(getPosition(node.node)));
}
final HColor color = getStyleArrow().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()); final HColor color = getStyleArrow().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());
for (ST_Agedge_s edge : edges) { for (ST_Agedge_s edge : edges) {
final JsonCurve curve = getCurve(edge, 13); final JsonCurve curve = getCurve(edge, 13);
curve.drawCurve(color, getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet())); curve.drawCurve(color, getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()));
curve.drawSpot( curve.drawSpot(getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet()).apply(color.bg()));
getStyleArrow().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet())
.apply(color.bg()));
} }
} }
private void initGraph(JsonValue root, List<String> highlighted) { private void initGraph(JsonValue root, List<Highlighted> highlighted) {
if (g != null) { if (g != null)
return; return;
}
Z.open(); Z.open();
try { try {
@ -268,9 +245,8 @@ public class SmetanaForJson {
final int lineHeight = 0; final int lineHeight = 0;
final String dotLabel = getDotLabel(size, isArray, colAwidth - 8, colBwidth - 8, lineHeight); 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("")); agsafeset(node, new CString("label"), new CString(dotLabel), new CString(""));
}
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("N" + node.UID + " ["); 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) { private String getDotLabel(int size, boolean isArray, int widthA, int widthB, int height) {
final StringBuilder sb = new StringBuilder(""); final StringBuilder sb = new StringBuilder("");
if (isArray == false) { if (isArray == false)
// "+height+"
sb.append("{_dim_" + height + "_" + widthA + "_|{"); sb.append("{_dim_" + height + "_" + widthA + "_|{");
}
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
sb.append("<P" + i + ">"); sb.append("<P" + i + ">");
sb.append("_dim_" + height + "_" + widthB + "_"); sb.append("_dim_" + height + "_" + widthB + "_");
if (i < size - 1) if (i < size - 1)
sb.append("|"); sb.append("|");
} }
if (isArray == false) { if (isArray == false)
sb.append("}}"); sb.append("}}");
}
return sb.toString(); return sb.toString();
} }

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.parser.StyleParser; 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.BlocLines;
import net.sourceforge.plantuml.utils.StringLocated; import net.sourceforge.plantuml.utils.StringLocated;
@ -108,13 +109,12 @@ public class StyleExtractor {
return line.getString().trim().equals("</style>"); return line.getString().trim().equals("</style>");
} }
public void applyStyles(ISkinParam skinParam) { public void applyStyles(ISkinParam skinParam) throws StyleParsingException {
if (style.size() > 0) { if (style.size() > 0) {
final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder(); final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder();
final BlocLines blocLines = BlocLines.from(style); 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); skinParam.muteStyle(modifiedStyle);
}
} }
} }

View File

@ -41,6 +41,7 @@ import java.util.List;
import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.LineBreakStrategy;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.awt.geom.XDimension2D; import net.sourceforge.plantuml.awt.geom.XDimension2D;
import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.Display; 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.PName;
import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style; 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.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.yaml.Highlighted;
//See TextBlockMap //See TextBlockMap
public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcolored { public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcolored {
private final List<Line> lines = new ArrayList<>(); private final List<Line> lines = new ArrayList<>();
private final Style styleNode;
private final Style styleNodeHightlight;
private final Style styleNodeHeader;
private final Style styleNodeHeaderHighlight;
private final ISkinParam skinParam; private final ISkinParam skinParam;
private double totalWidth; private double totalWidth;
private final JsonValue root; private final JsonValue root;
private final StyleBuilder styleBuilder;
private final SName diagramType;
static class Line { static class Line {
final TextBlock b1; final TextBlock b1;
final TextBlock b2; 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.b1 = b1;
this.b2 = b2; this.b2 = b2;
this.highlighted = highlighted; this.highlighted = highlighted;
} }
Line(TextBlock b1, boolean highlighted) { Line(TextBlock b1, Highlighted highlighted) {
this(b1, null, highlighted); this(b1, null, highlighted);
} }
@ -102,24 +106,18 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol
} }
private HColor getBackColor() { TextBlockJson(ISkinParam skinParam, JsonValue root, List<Highlighted> allHighlighteds) {
return styleNodeHightlight.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet()); this.styleBuilder = skinParam.getCurrentStyleBuilder();
} this.diagramType = skinParam.getUmlDiagramType() == UmlDiagramType.JSON ? SName.jsonDiagram : SName.yamlDiagram;
TextBlockJson(ISkinParam skinParam, JsonValue root, List<String> allHighlighteds, Style styleNode,
Style styleNodeHightlight, Style styleNodeHeader, Style styleNodeHeaderHighlight) {
this.skinParam = skinParam; this.skinParam = skinParam;
this.styleNode = styleNode;
this.styleNodeHeaderHighlight = styleNodeHeaderHighlight;
this.styleNodeHightlight = styleNodeHightlight;
this.styleNodeHeader = styleNodeHeader;
this.root = root; this.root = root;
if (root instanceof JsonObject) if (root instanceof JsonObject)
for (Member member : (JsonObject) root) { for (Member member : (JsonObject) root) {
final String key = member.getName(); final String key = member.getName();
final String value = getShortString(member.getValue()); 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 block1 = getTextBlock(getStyleToUse(true, highlighted), key);
final TextBlock block2 = getTextBlock(getStyleToUse(false, highlighted), value); final TextBlock block2 = getTextBlock(getStyleToUse(false, highlighted), value);
this.lines.add(new Line(block1, block2, highlighted)); this.lines.add(new Line(block1, block2, highlighted));
@ -127,7 +125,7 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol
if (root instanceof JsonArray) { if (root instanceof JsonArray) {
int i = 0; int i = 0;
for (JsonValue value : (JsonArray) root) { 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)); final TextBlock block2 = getTextBlock(getStyleToUse(false, highlighted), getShortString(value));
this.lines.add(new Line(block2, highlighted)); this.lines.add(new Line(block2, highlighted));
i++; i++;
@ -135,25 +133,29 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol
} }
} }
private Style getStyleToUse(boolean header, boolean highlighted) { private Style getStyleToUse(boolean header, Highlighted highlighted) {
if (header && highlighted) final StyleSignature signature;
return styleNodeHeaderHighlight; 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 signature.getMergedStyle(styleBuilder);
return styleNodeHightlight;
if (header)
return styleNodeHeader;
return styleNode;
} }
private boolean isHighlighted(String key, List<String> highlighted) { private Highlighted isHighlighted(String key, List<Highlighted> highlighted) {
for (String tmp : highlighted) for (Highlighted tmp : highlighted)
if (tmp.trim().equals("\"" + key + "\"")) if (tmp.isKeyHighlight(key))
return true; return tmp;
return false; return null;
} }
public int size() { public int size() {
@ -260,6 +262,8 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol
final double widthColB = getWidthColB(stringBounder); final double widthColB = getWidthColB(stringBounder);
double y = 0; 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()); final UGraphic ugNode = styleNode.applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet());
for (Line line : lines) { for (Line line : lines) {
final double heightOfRow = line.getHeightOfRow(stringBounder); final double heightOfRow = line.getHeightOfRow(stringBounder);
@ -283,9 +287,14 @@ public class TextBlockJson extends AbstractTextBlock implements TextBlockBackcol
for (Line line : lines) { for (Line line : lines) {
final UGraphic ugline = ugSeparator.apply(UTranslate.dy(y)); final UGraphic ugline = ugSeparator.apply(UTranslate.dy(y));
final double heightOfRow = line.getHeightOfRow(stringBounder); final double heightOfRow = line.getHeightOfRow(stringBounder);
if (line.highlighted) { if (line.highlighted != null) {
final URectangle back = new URectangle(trueWidth - 2, heightOfRow).rounded(4); 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) if (y > 0)

View File

@ -57,6 +57,8 @@ import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder; import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
public class NServer { public class NServer {
@ -65,6 +67,7 @@ public class NServer {
private USymbol shape = USymbols.RECTANGLE; private USymbol shape = USymbols.RECTANGLE;
private final String name; private final String name;
private String description; private String description;
private String backcolor;
private final NBar bar; private final NBar bar;
private boolean printFirstLink = true; private boolean printFirstLink = true;
@ -86,12 +89,12 @@ public class NServer {
} }
private TextBlock toTextBlock(String s, ISkinParam skinParam, SName sname) { private TextBlock toTextBlock(String s, ISkinParam skinParam, SName sname) {
if (s == null) if (s == null)
return null; return null;
if (s.length() == 0) if (s.length() == 0)
return TextBlockUtils.empty(0, 0); return TextBlockUtils.empty(0, 0);
s = s.replace(", ", "\\n"); s = s.replace(", ", "\\n");
return Display.getWithNewlines(s).create(getFontConfiguration(skinParam, sname), HorizontalAlignment.LEFT, return Display.getWithNewlines(s).create(getFontConfiguration(skinParam, sname), HorizontalAlignment.LEFT,
skinParam); skinParam);
@ -110,13 +113,18 @@ public class NServer {
public LinkedElement getLinkedElement(double topMargin, Map<Network, String> conns, List<Network> networks, public LinkedElement getLinkedElement(double topMargin, Map<Network, String> conns, List<Network> networks,
ISkinParam skinParam) { ISkinParam skinParam) {
final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder(); final StyleBuilder styleBuilder = skinParam.getCurrentStyleBuilder();
final SymbolContext symbolContext = getStyleDefinition(SName.server).getMergedStyle(styleBuilder) SymbolContext symbolContext = getStyleDefinition(SName.server).getMergedStyle(styleBuilder)
.getSymbolContext(skinParam.getIHtmlColorSet()); .getSymbolContext(skinParam.getIHtmlColorSet());
if (backcolor != null)
try {
final HColor back = skinParam.getIHtmlColorSet().getColor(backcolor);
symbolContext = symbolContext.withBackColor(back);
} catch (NoSuchColorException e) {
}
final Map<Network, TextBlock> conns2 = new LinkedHashMap<Network, TextBlock>(); final Map<Network, TextBlock> conns2 = new LinkedHashMap<Network, TextBlock>();
for (Entry<Network, String> ent : conns.entrySet()) for (Entry<Network, String> ent : conns.entrySet())
conns2.put(ent.getKey(), toTextBlock(ent.getValue(), skinParam, SName.arrow)); conns2.put(ent.getKey(), toTextBlock(ent.getValue(), skinParam, SName.arrow));
final TextBlock desc = toTextBlock(getDescription(), skinParam, SName.server); final TextBlock desc = toTextBlock(getDescription(), skinParam, SName.server);
final TextBlock box = getShape().asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), 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) { public void connectTo(Network network, String address) {
if (address == null) if (address == null)
address = ""; address = "";
if (address.length() == 0 && connections.containsKey(network)) if (address.length() == 0 && connections.containsKey(network))
return; return;
connections.put(network, address); connections.put(network, address);
if (bar.getStart() == null) if (bar.getStart() == null)
bar.addStage(network.getNstage()); bar.addStage(network.getNstage());
@ -142,14 +150,18 @@ public class NServer {
} }
public void updateProperties(Map<String, String> props) { public void updateProperties(Map<String, String> props) {
final String description = props.get("description"); if (props.get("description") != null)
if (description != null) this.description = props.get("description");
this.setDescription(description); this.backcolor = props.get("color");
final String shape = props.get("shape"); final String shape = props.get("shape");
if (shape != null) if (shape != null) {
this.setShape(shape); final USymbol shapeFromString = USymbols.fromString(shape, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE,
PackageStyle.RECTANGLE);
if (shapeFromString != null)
this.shape = shapeFromString;
}
} }
@Override @Override
@ -171,22 +183,10 @@ public class NServer {
return description; return description;
} }
public final void setDescription(String description) {
this.description = description;
}
public final String getName() { public final String getName() {
return name; 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() { public final USymbol getShape() {
return shape; return shape;
} }

View File

@ -54,11 +54,11 @@ public class RegexExpression {
result.add(new ReToken(ReTokenType.ANCHOR, s)); result.add(new ReToken(ReTokenType.ANCHOR, s));
} else if (isEscapedChar(it)) { } else if (isEscapedChar(it)) {
result.add(new ReToken(ReTokenType.ESCAPED_CHAR, "" + it.peek(1))); result.add(new ReToken(ReTokenType.ESCAPED_CHAR, "" + it.peek(1)));
it.next(); it.jump();
it.next(); it.jump();
} else if (current == '|') { } else if (current == '|') {
result.add(new ReToken(ReTokenType.ALTERNATIVE, "|")); result.add(new ReToken(ReTokenType.ALTERNATIVE, "|"));
it.next(); it.jump();
} else if (current == '[') { } else if (current == '[') {
final String s = readGroup(it); final String s = readGroup(it);
result.add(new ReToken(ReTokenType.GROUP, s)); result.add(new ReToken(ReTokenType.GROUP, s));
@ -67,7 +67,7 @@ public class RegexExpression {
result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, s)); result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, s));
} else if (current == ')') { } else if (current == ')') {
result.add(new ReToken(ReTokenType.PARENTHESIS_CLOSE, ")")); result.add(new ReToken(ReTokenType.PARENTHESIS_CLOSE, ")"));
it.next(); it.jump();
} else if (isStartQuantifier(it)) { } else if (isStartQuantifier(it)) {
final String s = readQuantifier(it); final String s = readQuantifier(it);
result.add(new ReToken(ReTokenType.QUANTIFIER, s)); result.add(new ReToken(ReTokenType.QUANTIFIER, s));
@ -76,7 +76,7 @@ public class RegexExpression {
result.add(new ReToken(ReTokenType.CLASS, s)); result.add(new ReToken(ReTokenType.CLASS, s));
} else if (isSimpleLetter(current)) { } else if (isSimpleLetter(current)) {
result.add(new ReToken(ReTokenType.SIMPLE_CHAR, "" + current)); result.add(new ReToken(ReTokenType.SIMPLE_CHAR, "" + current));
it.next(); it.jump();
} else { } else {
throw new IllegalStateException(); throw new IllegalStateException();
} }
@ -95,17 +95,17 @@ public class RegexExpression {
private static String readOpenParenthesis(CharInspector it) { private static String readOpenParenthesis(CharInspector it) {
final char current0 = it.peek(0); final char current0 = it.peek(0);
it.next(); it.jump();
final StringBuilder result = new StringBuilder(); final StringBuilder result = new StringBuilder();
result.append(current0); result.append(current0);
if (it.peek(0) == '?' && it.peek(1) == ':') { if (it.peek(0) == '?' && it.peek(1) == ':') {
it.next(); it.jump();
it.next(); it.jump();
result.append("?:"); result.append("?:");
} }
if (it.peek(0) == '?' && it.peek(1) == '!') { if (it.peek(0) == '?' && it.peek(1) == '!') {
it.next(); it.jump();
it.next(); it.jump();
result.append("?!"); result.append("?!");
} }
return result.toString(); return result.toString();
@ -120,20 +120,20 @@ public class RegexExpression {
private static String readQuantifier(CharInspector it) { private static String readQuantifier(CharInspector it) {
final char current0 = it.peek(0); final char current0 = it.peek(0);
it.next(); it.jump();
final StringBuilder result = new StringBuilder(); final StringBuilder result = new StringBuilder();
result.append(current0); result.append(current0);
if (current0 == '{') if (current0 == '{')
while (it.peek(0) != 0) { while (it.peek(0) != 0) {
final char ch = it.peek(0); final char ch = it.peek(0);
result.append(ch); result.append(ch);
it.next(); it.jump();
if (ch == '}') if (ch == '}')
break; break;
} }
if (it.peek(0) == '?') { if (it.peek(0) == '?') {
result.append('?'); result.append('?');
it.next(); it.jump();
} }
return result.toString(); return result.toString();
} }
@ -154,17 +154,17 @@ public class RegexExpression {
final char current0 = it.peek(0); final char current0 = it.peek(0);
if (current0 != '[') if (current0 != '[')
throw new IllegalStateException(); throw new IllegalStateException();
it.next(); it.jump();
final StringBuilder result = new StringBuilder(); final StringBuilder result = new StringBuilder();
while (it.peek(0) != 0) { while (it.peek(0) != 0) {
char ch = it.peek(0); char ch = it.peek(0);
it.next(); it.jump();
if (ch == ']') if (ch == ']')
break; break;
result.append(ch); result.append(ch);
if (ch == '\\') { if (ch == '\\') {
ch = it.peek(0); ch = it.peek(0);
it.next(); it.jump();
result.append(ch); result.append(ch);
} }
@ -175,13 +175,13 @@ public class RegexExpression {
private static String readClass(CharInspector it) { private static String readClass(CharInspector it) {
final char current0 = it.peek(0); final char current0 = it.peek(0);
if (current0 == '.') { if (current0 == '.') {
it.next(); it.jump();
return "" + current0; return "" + current0;
} }
if (current0 == '\\') { if (current0 == '\\') {
it.next(); it.jump();
final String result = "" + current0 + it.peek(0); final String result = "" + current0 + it.peek(0);
it.next(); it.jump();
return result; return result;
} }
throw new IllegalStateException(); throw new IllegalStateException();
@ -218,13 +218,13 @@ public class RegexExpression {
private static String readAnchor(CharInspector it) { private static String readAnchor(CharInspector it) {
final char current0 = it.peek(0); final char current0 = it.peek(0);
if (current0 == '^' || current0 == '$') { if (current0 == '^' || current0 == '$') {
it.next(); it.jump();
return "" + current0; return "" + current0;
} }
if (current0 == '\\') { if (current0 == '\\') {
it.next(); it.jump();
final String result = "" + current0 + it.peek(0); final String result = "" + current0 + it.peek(0);
it.next(); it.jump();
return result; return result;
} }
throw new IllegalStateException(); throw new IllegalStateException();

View File

@ -41,7 +41,6 @@ import java.util.Objects;
import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.Guillemet;
import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.LineBreakStrategy;
import net.sourceforge.plantuml.SpriteContainer; import net.sourceforge.plantuml.SpriteContainer;
import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Parser;
@ -115,11 +114,6 @@ public class Dictionary implements SpriteContainer, ISkinSimple {
} }
@Override
public LineBreakStrategy wrapWidth() {
return LineBreakStrategy.NONE;
}
@Override @Override
public void copyAllFrom(Map<String, String> other) { public void copyAllFrom(Map<String, String> other) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -62,7 +62,6 @@ import h.ST_Agrec_s;
import h.ST_GVC_s; import h.ST_GVC_s;
import h.ST_boxf; import h.ST_boxf;
import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagram; 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.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.log.Logme; 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.Bibliotekon;
import net.sourceforge.plantuml.svek.Cluster; import net.sourceforge.plantuml.svek.Cluster;
import net.sourceforge.plantuml.svek.ClusterHeader; import net.sourceforge.plantuml.svek.ClusterHeader;
@ -435,10 +437,17 @@ public class CucaDiagramFileMakerSmetana implements CucaDiagramFileMaker {
this.exportGroups(cluster1, group); 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) { private TextBlock getLabel(Link link) {
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1; final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
ISkinParam skinParam = diagram.getSkinParam(); 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, final TextBlock label = link.getLabel().create(labelFont,
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam); skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
if (TextBlockUtils.isEmpty(label, stringBounder)) if (TextBlockUtils.isEmpty(label, stringBounder))
@ -454,7 +463,8 @@ public class CucaDiagramFileMakerSmetana implements CucaDiagramFileMaker {
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1; final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
ISkinParam skinParam = diagram.getSkinParam(); 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, final TextBlock label = Display.getWithNewlines(tmp).create(labelFont,
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam); skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
if (TextBlockUtils.isEmpty(label, stringBounder)) if (TextBlockUtils.isEmpty(label, stringBounder))

View File

@ -42,6 +42,7 @@ import h.ST_pointf;
import h.ST_splines; import h.ST_splines;
import h.ST_textlabel_t; import h.ST_textlabel_t;
import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.awt.geom.XPoint2D; import net.sourceforge.plantuml.awt.geom.XPoint2D;
import net.sourceforge.plantuml.cucadiagram.ICucaDiagram; import net.sourceforge.plantuml.cucadiagram.ICucaDiagram;
import net.sourceforge.plantuml.cucadiagram.Link; 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.UDrawable;
import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.posimo.DotPath; import net.sourceforge.plantuml.posimo.DotPath;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignatureBasic; import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactory; import net.sourceforge.plantuml.svek.extremity.ExtremityFactory;
import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UEllipse;
@ -73,7 +74,6 @@ public class SmetanaPath implements UDrawable {
private final TextBlock label; private final TextBlock label;
private final TextBlock headLabel; private final TextBlock headLabel;
private final TextBlock tailLabel; private final TextBlock tailLabel;
private final Rose rose = new Rose();
public SmetanaPath(Link link, ST_Agedge_s edge, YMirror ymirror, ICucaDiagram diagram, TextBlock label, public SmetanaPath(Link link, ST_Agedge_s edge, YMirror ymirror, ICucaDiagram diagram, TextBlock label,
TextBlock tailLabel, TextBlock headLabel) { TextBlock tailLabel, TextBlock headLabel) {
@ -91,10 +91,7 @@ public class SmetanaPath implements UDrawable {
if (link.isHidden()) if (link.isHidden())
return; return;
HColor color = StyleSignatureBasic HColor color = getStyle().value(PName.LineColor).asColor(diagram.getSkinParam().getIHtmlColorSet());
.of(SName.root, SName.element, diagram.getUmlDiagramType().getStyleName(), SName.arrow)
.getMergedStyle(diagram.getSkinParam().getCurrentStyleBuilder()).value(PName.LineColor)
.asColor(diagram.getSkinParam().getIHtmlColorSet());
if (this.link.getColors() != null) { if (this.link.getColors() != null) {
final HColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE); 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) if (link.getColors() != null && link.getColors().getSpecificLineStroke() != null)
stroke = link.getColors().getSpecificLineStroke(); stroke = link.getColors().getSpecificLineStroke();
final Url url = link.getUrl();
if (url != null)
ug.startUrl(url);
ug.apply(stroke).apply(color).draw(dotPath); ug.apply(stroke).apply(color).draw(dotPath);
printExtremityAtStart(ug.apply(color)); printExtremityAtStart(ug.apply(color));
printExtremityAtEnd(ug.apply(color)); printExtremityAtEnd(ug.apply(color));
if (url != null)
ug.closeUrl();
} }
if (getLabelRectangleTranslate("label") != null) if (getLabelRectangleTranslate("label") != null)
label.drawU(ug.apply(getLabelRectangleTranslate("label"))); 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) { private void printExtremityAtStart(UGraphic ug) {
final ExtremityFactory extremityFactory2 = link.getType().getDecor2() final ExtremityFactory extremityFactory2 = link.getType().getDecor2()
.getExtremityFactoryComplete(diagram.getSkinParam().getBackgroundColor()); .getExtremityFactoryComplete(diagram.getSkinParam().getBackgroundColor());

View File

@ -64,7 +64,7 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements
public ComponentRoseNote(Style style, Display strings, double paddingX, double paddingY, public ComponentRoseNote(Style style, Display strings, double paddingX, double paddingY,
ISkinSimple spriteContainer, HorizontalAlignment textAlignment, HorizontalAlignment position, ISkinSimple spriteContainer, HorizontalAlignment textAlignment, HorizontalAlignment position,
Colors colors) { 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); spriteContainer, strings, true);
this.paddingX = paddingX; this.paddingX = paddingX;
this.paddingY = paddingY; this.paddingY = paddingY;

View File

@ -55,7 +55,7 @@ final public class ComponentRoseNoteBox extends AbstractTextualComponent {
private final double roundCorner; private final double roundCorner;
public ComponentRoseNoteBox(Style style, Display strings, ISkinSimple spriteContainer, Colors colors) { 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.symbolContext = style.getSymbolContext(getIHtmlColorSet(), colors);
this.roundCorner = style.value(PName.RoundCorner).asInt(false); this.roundCorner = style.value(PName.RoundCorner).asInt(false);

View File

@ -54,7 +54,7 @@ final public class ComponentRoseNoteHexagonal extends AbstractTextualComponent {
private final SymbolContext symbolContext; private final SymbolContext symbolContext;
public ComponentRoseNoteHexagonal(Style style, Display strings, ISkinSimple spriteContainer, Colors colors) { 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); this.symbolContext = style.getSymbolContext(getIHtmlColorSet(), colors);

View File

@ -48,6 +48,7 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.style.parser.StyleParser; 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.BlocLines;
import net.sourceforge.plantuml.utils.LineLocation; import net.sourceforge.plantuml.utils.LineLocation;
@ -84,17 +85,19 @@ public class CommandStyleImport extends SingleLineCommand2<TitledDiagram> {
lines = BlocLines.load(f, location); lines = BlocLines.load(f, location);
} else { } else {
final InputStream internalIs = StyleLoader.class.getResourceAsStream("/skin/" + path); final InputStream internalIs = StyleLoader.class.getResourceAsStream("/skin/" + path);
if (internalIs != null) { if (internalIs != null)
lines = BlocLines.load(internalIs, location); lines = BlocLines.load(internalIs, location);
}
} }
if (lines == null) { if (lines == null)
return CommandExecutionResult.error("Cannot read: " + path); return CommandExecutionResult.error("Cannot read: " + path);
}
final StyleBuilder styleBuilder = diagram.getSkinParam().getCurrentStyleBuilder(); final StyleBuilder styleBuilder = diagram.getSkinParam().getCurrentStyleBuilder();
for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder)) { for (Style modifiedStyle : StyleParser.parse(lines, styleBuilder))
diagram.getSkinParam().muteStyle(modifiedStyle); diagram.getSkinParam().muteStyle(modifiedStyle);
}
} catch (StyleParsingException e) {
return CommandExecutionResult.error("Error in style definition: " + e.getMessage());
} catch (IOException e) { } catch (IOException e) {
return CommandExecutionResult.error("Cannot read: " + path); return CommandExecutionResult.error("Cannot read: " + path);
} }

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.style.parser.StyleParser; 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.BlocLines;
public class CommandStyleMultilinesCSS extends CommandMultilines2<TitledDiagram> { public class CommandStyleMultilinesCSS extends CommandMultilines2<TitledDiagram> {
@ -57,7 +58,7 @@ public class CommandStyleMultilinesCSS extends CommandMultilines2<TitledDiagram>
@Override @Override
public String getPatternEnd() { public String getPatternEnd() {
return "^[%s]*\\</style\\>[%s]*$"; return "^[%s]*\\</?style\\>[%s]*$";
} }
private static IRegex getRegexConcat() { private static IRegex getRegexConcat() {
@ -75,6 +76,8 @@ public class CommandStyleMultilinesCSS extends CommandMultilines2<TitledDiagram>
((SkinParam) diagram.getSkinParam()).applyPendingStyleMigration(); ((SkinParam) diagram.getSkinParam()).applyPendingStyleMigration();
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} catch (StyleParsingException e) {
return CommandExecutionResult.error("Error in style definition: " + e.getMessage());
} catch (NoStyleAvailableException e) { } catch (NoStyleAvailableException e) {
// Logme.error(e); // Logme.error(e);
return CommandExecutionResult.error("General failure: no style available."); return CommandExecutionResult.error("General failure: no style available.");

View File

@ -235,6 +235,9 @@ public class FromSkinparamToStyle {
// addConvert("sequenceStereotypeFontName", PName.FontName, SName.stereotype); // addConvert("sequenceStereotypeFontName", PName.FontName, SName.stereotype);
addConvert("lifelineStrategy", PName.LineStyle, SName.lifeLine); 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")) { } else if (key.equals("lifelinestrategy")) {
if (value.equalsIgnoreCase("solid")) if (value.equalsIgnoreCase("solid"))
value = "0"; value = "0";
} else if (key.equals("hyperlinkunderline")) {
if (value.equalsIgnoreCase("false"))
value = "0";
} }
if (value.equalsIgnoreCase("right:right")) if (value.equalsIgnoreCase("right:right"))

View File

@ -227,7 +227,7 @@ public class Style {
Style result = this.eventuallyOverride(PName.LineThickness, stroke.getThickness()); Style result = this.eventuallyOverride(PName.LineThickness, stroke.getThickness());
final double space = stroke.getDashSpace(); final double space = stroke.getDashSpace();
final double visible = stroke.getDashVisible(); final double visible = stroke.getDashVisible();
result = result.eventuallyOverride(PName.LineStyle, "" + visible + ";" + space); result = result.eventuallyOverride(PName.LineStyle, "" + visible + "-" + space);
return result; return result;
} }

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.FileSystem;
import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.style.parser.StyleParser; 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.BlocLines;
import net.sourceforge.plantuml.utils.LineLocationImpl; import net.sourceforge.plantuml.utils.LineLocationImpl;
import net.sourceforge.plantuml.utils.Log; import net.sourceforge.plantuml.utils.Log;
@ -59,7 +60,7 @@ public class StyleLoader {
private StyleBuilder styleBuilder; private StyleBuilder styleBuilder;
public StyleBuilder loadSkin(String filename) throws IOException { public StyleBuilder loadSkin(String filename) throws IOException, StyleParsingException {
this.styleBuilder = new StyleBuilder(skinParam); this.styleBuilder = new StyleBuilder(skinParam);
final InputStream internalIs = getInputStreamForStyle(filename); final InputStream internalIs = getInputStreamForStyle(filename);
@ -101,7 +102,7 @@ public class StyleLoader {
return internalIs; return internalIs;
} }
private void loadSkinInternal(final BlocLines lines) { private void loadSkinInternal(final BlocLines lines) throws StyleParsingException {
for (Style newStyle : StyleParser.parse(lines, styleBuilder)) for (Style newStyle : StyleParser.parse(lines, styleBuilder))
this.styleBuilder.loadInternal(newStyle.getSignature(), newStyle); this.styleBuilder.loadInternal(newStyle.getSignature(), newStyle);
} }

View File

@ -38,29 +38,38 @@ package net.sourceforge.plantuml.style.parser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; 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.StyleSignatureBasic;
import net.sourceforge.plantuml.style.Value;
class Context { class Context {
private final List<String> data = new ArrayList<String>(); private final List<String> data = new ArrayList<String>();
private final Map<PName, Value> map = new EnumMap<>(PName.class);
private Context parent;
public Context push(String newString) { public Context push(String newString) {
if (newString.startsWith(":"))
newString = newString.substring(1);
final Context result = new Context(); final Context result = new Context();
result.data.addAll(this.data); result.data.addAll(this.data);
result.data.add(newString); result.data.add(newString);
result.parent = this;
return result; return result;
} }
public Context pop() { public Context pop() {
if (size() == 0) if (size() == 0)
throw new IllegalStateException(); throw new IllegalStateException();
final Context result = new Context(); return this.parent;
result.data.addAll(this.data.subList(0, this.data.size() - 1));
return result;
} }
@Override @Override
@ -98,4 +107,22 @@ class Context {
return Collections.unmodifiableCollection(results); return Collections.unmodifiableCollection(results);
} }
public void putInContext(PName key, Value value) {
map.put(key, value);
}
public Collection<Style> toStyles() {
final Collection<Style> result = new ArrayList<>();
final Collection<StyleSignatureBasic> signatures = toSignatures();
for (StyleSignatureBasic signature : signatures) {
Map<PName, Value> tmp = map;
if (signature.isWithDot())
tmp = StyleLoader.addPriorityForStereotype(tmp);
if (tmp.size() > 0)
result.add(new Style(signature, tmp));
}
return result;
}
} }

View File

@ -40,7 +40,7 @@ import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class CssVariables { class CssVariables {
private final Map<String, String> variables = new HashMap<>(); private final Map<String, String> variables = new HashMap<>();
@ -53,6 +53,12 @@ public class CssVariables {
variables.put(m.group(1), m.group(2)); variables.put(m.group(1), m.group(2));
} }
public void learn(String var, String value) {
if (var.startsWith("--"))
var = var.substring(2);
variables.put(var, value);
}
public String value(String v) { public String value(String v) {
if (v.startsWith("var(")) { if (v.startsWith("var(")) {
final Matcher m = retrieve.matcher(v); final Matcher m = retrieve.matcher(v);

View File

@ -38,118 +38,283 @@ package net.sourceforge.plantuml.style.parser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.List; import java.util.List;
import java.util.Map;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.style.AutomaticCounter; import net.sourceforge.plantuml.style.AutomaticCounter;
import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleLoader;
import net.sourceforge.plantuml.style.StyleScheme; import net.sourceforge.plantuml.style.StyleScheme;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.style.Value; import net.sourceforge.plantuml.style.Value;
import net.sourceforge.plantuml.style.ValueImpl; import net.sourceforge.plantuml.style.ValueImpl;
import net.sourceforge.plantuml.utils.BlocLines; import net.sourceforge.plantuml.utils.BlocLines;
import net.sourceforge.plantuml.utils.StringLocated; import net.sourceforge.plantuml.utils.CharInspector;
import net.sourceforge.plantuml.utils.Inspector;
import net.sourceforge.plantuml.utils.InspectorUtils;
public class StyleParser { public class StyleParser {
private final static String KEYNAMES = "[-.\\w(), ]+?"; public static Collection<Style> parse(BlocLines lines, AutomaticCounter counter) throws StyleParsingException {
private final static Pattern2 keyName = MyPattern.cmpile("^[:]?(" + KEYNAMES + ")([%s]+\\*)?[%s]*\\{$");
private final static Pattern2 propertyAndValue = MyPattern.cmpile("^([\\w]+):?[%s]+(.*?);?$"); if (lines.size() == 0)
private final static Pattern2 closeBracket = MyPattern.cmpile("^\\}$"); return Collections.emptyList();
final List<StyleToken> tokens = parse(lines.inspectorWithNewlines());
public static Collection<Style> parse(BlocLines lines, AutomaticCounter counter) {
lines = lines.eventuallyMoveAllEmptyBracket();
final List<Style> result = new ArrayList<>(); final List<Style> result = new ArrayList<>();
final CssVariables variables = new CssVariables(); final CssVariables variables = new CssVariables();
StyleScheme scheme = StyleScheme.REGULAR; StyleScheme scheme = StyleScheme.REGULAR;
Context context = new Context(); Context context = new Context();
final List<Map<PName, Value>> maps = new ArrayList<Map<PName, Value>>();
boolean inComment = false;
for (StringLocated s : lines) {
String trimmed = s.getTrimmed().getString();
if (trimmed.startsWith("/*") || trimmed.endsWith("*/")) // System.err.println("tokens=" + tokens.size());
// if (tokens.size() < 100)
// for (StyleToken t : tokens)
// System.err.println(t);
for (Inspector<StyleToken> ins = InspectorUtils.inspector(tokens); ins.peek(0) != null;) {
final StyleToken token = ins.peek(0);
ins.jump();
if (token.getType() == StyleTokenType.NEWLINE)
continue; continue;
if (trimmed.startsWith("/'") || trimmed.endsWith("'/")) if (token.getType() == StyleTokenType.SEMICOLON)
continue; continue;
if (trimmed.startsWith("/*") || trimmed.startsWith("/'")) { if (ins.peek(0).getType() == StyleTokenType.COMMA) {
inComment = true; final String full = token.getData() + readWithComma(ins);
continue; skipNewLines(ins);
if (ins.peek(0).getType() == StyleTokenType.OPEN_BRACKET) {
context = context.push(full);
ins.jump();
continue;
}
throw new IllegalStateException();
} }
if (trimmed.endsWith("*/") || trimmed.endsWith("'/")) { if (token.getType() == StyleTokenType.STRING) {
inComment = false; String full = token.getData();
continue; if (ins.peek(0).getType() == StyleTokenType.STAR) {
} ins.jump();
if (inComment) full += "*";
continue; }
skipNewLines(ins);
if (ins.peek(0).getType() == StyleTokenType.OPEN_BRACKET) {
context = context.push(full);
ins.jump();
continue;
}
skipColon(ins);
if (token.getData().startsWith("--")) {
variables.learn(token.getData(), readValue(ins));
} else if (ins.peek(0).getType() == StyleTokenType.STRING) {
final String valueString = variables.value(readValue(ins));
final String keyString = token.getData();
final PName key = PName.getFromName(keyString, scheme);
if (key == null) {
// System.err.println("Error with key " + keyString);
} else {
final Value value = scheme == StyleScheme.REGULAR ? //
ValueImpl.regular(valueString, counter) : ValueImpl.dark(valueString, counter);
context.putInContext(key, value);
}
} else {
throw new StyleParsingException("parsing");
}
if (trimmed.matches("@media.*dark.*\\{")) { } else if (token.getType() == StyleTokenType.CLOSE_BRACKET) {
for (Style st : context.toStyles())
result.add(st);
if (context.size() > 0)
context = context.pop();
} else if (token.getType() == StyleTokenType.AROBASE_MEDIA) {
scheme = StyleScheme.DARK; scheme = StyleScheme.DARK;
continue; continue;
} } else if (token.getType() == StyleTokenType.COLON && ins.peek(0).getType() == StyleTokenType.STRING
&& ins.peek(1).getType() == StyleTokenType.OPEN_BRACKET) {
if (trimmed.startsWith("--")) { final String full = token.getData() + ins.peek(0).getData();
variables.learn(trimmed); context = context.push(full);
ins.jump();
ins.jump();
continue; continue;
} } else if (token.getType() == StyleTokenType.COLON && ins.peek(0).getType() == StyleTokenType.STRING
&& ins.peek(1).getType() == StyleTokenType.STAR
final int x = trimmed.lastIndexOf("//"); && ins.peek(2).getType() == StyleTokenType.OPEN_BRACKET) {
if (x != -1) final String full = token.getData() + ins.peek(0).getData() + ins.peek(1).getData();
trimmed = trimmed.substring(0, x).trim(); context = context.push(full);
ins.jump();
final Matcher2 mKeyNames = keyName.matcher(trimmed); ins.jump();
if (mKeyNames.find()) { ins.jump();
String names = mKeyNames.group(1);
final boolean isRecurse = mKeyNames.group(2) != null;
if (isRecurse)
names += "*";
context = context.push(names);
maps.add(new EnumMap<PName, Value>(PName.class));
continue; continue;
} } else if (token.getType() == StyleTokenType.OPEN_BRACKET) {
final Matcher2 mPropertyAndValue = propertyAndValue.matcher(trimmed); throw new StyleParsingException("Invalid open bracket");
if (mPropertyAndValue.find()) { } else {
final PName key = PName.getFromName(mPropertyAndValue.group(1), scheme); throw new IllegalStateException(token.toString());
final String value = variables.value(mPropertyAndValue.group(2));
if (key != null && maps.size() > 0)
maps.get(maps.size() - 1).put(key, //
scheme == StyleScheme.REGULAR ? //
ValueImpl.regular(value, counter) : ValueImpl.dark(value, counter));
continue;
}
final Matcher2 mCloseBracket = closeBracket.matcher(trimmed);
if (mCloseBracket.find()) {
if (context.size() > 0) {
final Collection<StyleSignatureBasic> signatures = context.toSignatures();
for (StyleSignatureBasic signature : signatures) {
Map<PName, Value> tmp = maps.get(maps.size() - 1);
if (signature.isWithDot())
tmp = StyleLoader.addPriorityForStereotype(tmp);
if (tmp.size() > 0) {
final Style style = new Style(signature, tmp);
result.add(style);
}
}
context = context.pop();
maps.remove(maps.size() - 1);
} else {
scheme = StyleScheme.REGULAR;
}
} }
} }
return Collections.unmodifiableList(result); return Collections.unmodifiableList(result);
}
private static String readWithComma(Inspector<StyleToken> ins) {
final StringBuilder result = new StringBuilder();
while (ins.peek(0) != null) {
final StyleToken current = ins.peek(0);
if (current.getType() != StyleTokenType.STRING && current.getType() != StyleTokenType.COMMA)
return result.toString();
result.append(current.getData());
ins.jump();
}
return result.toString();
}
private static String readValue(Inspector<StyleToken> ins) throws StyleParsingException {
final StringBuilder result = new StringBuilder();
while (ins.peek(0) != null) {
final StyleToken current = ins.peek(0);
if (current.getType() == StyleTokenType.NEWLINE || current.getType() == StyleTokenType.SEMICOLON
|| current.getType() == StyleTokenType.CLOSE_BRACKET)
return result.toString();
if (current.getType() == StyleTokenType.STRING) {
if (result.length() > 0)
result.append(' ');
result.append(current.getData());
ins.jump();
} else if (current.getType() == StyleTokenType.COLON) {
result.append(current.getData());
ins.jump();
if (ins.peek(0).getType() == StyleTokenType.STRING) {
result.append(ins.peek(0).getData());
ins.jump();
} else
throw new StyleParsingException("bad definition");
} else
throw new StyleParsingException("bad definition");
}
return result.toString();
}
private static void skipNewLines(Inspector<StyleToken> ins) {
while (true) {
final StyleToken token = ins.peek(0);
if (token == null || token.getType() != StyleTokenType.NEWLINE)
return;
ins.jump();
}
}
private static void skipColon(Inspector<StyleToken> ins) {
while (true) {
final StyleToken token = ins.peek(0);
if (token == null || token.getType() != StyleTokenType.COLON)
return;
ins.jump();
}
}
private static List<StyleToken> parse(CharInspector ins) throws StyleParsingException {
final List<StyleToken> result = new ArrayList<>();
while (true) {
final char current = ins.peek(0);
if (current == '\0')
break;
// System.err.println("current=" + current);
if (current == ' ' || current == '\t') {
ins.jump();
// Skipping
} else if (current == '/' && ins.peek(1) == '/') {
jumpUntil(ins, '\n');
} else if (current == '/' && ins.peek(1) == '\'') {
jumpUntil(ins, '\'', '/');
} else if (current == '/' && ins.peek(1) == '*') {
jumpUntil(ins, '*', '/');
} else if (current == ',') {
result.add(new StyleToken(StyleTokenType.COMMA, ","));
ins.jump();
} else if (current == ';') {
result.add(new StyleToken(StyleTokenType.SEMICOLON, ";"));
ins.jump();
} else if (current == '\n' || current == '\r') {
result.add(new StyleToken(StyleTokenType.NEWLINE, "NEWLINE"));
ins.jump();
} else if (current == '*') {
result.add(new StyleToken(StyleTokenType.STAR, "*"));
ins.jump();
} else if (current == ':') {
result.add(new StyleToken(StyleTokenType.COLON, ":"));
ins.jump();
} else if (current == '{') {
result.add(new StyleToken(StyleTokenType.OPEN_BRACKET, "{"));
ins.jump();
} else if (current == '}') {
result.add(new StyleToken(StyleTokenType.CLOSE_BRACKET, "}"));
ins.jump();
} else if (current == '@') {
result.add(new StyleToken(StyleTokenType.AROBASE_MEDIA, readArobaseMedia(ins)));
} else {
final String s = readString(ins);
if (s.startsWith("<"))
throw new StyleParsingException("Cannot understand <");
result.add(new StyleToken(StyleTokenType.STRING, s));
}
}
return result;
} }
private static void jumpUntil(CharInspector ins, char ch1) {
while (ins.peek(0) != 0) {
if (ins.peek(0) == ch1) {
ins.jump();
return;
}
ins.jump();
}
}
private static void jumpUntil(CharInspector ins, char ch1, char ch2) {
while (ins.peek(0) != 0) {
if (ins.peek(0) == ch1 && ins.peek(1) == ch2) {
ins.jump();
ins.jump();
return;
}
ins.jump();
}
}
private static String readArobaseMedia(CharInspector ins) {
final char current0 = ins.peek(0);
if (current0 != '@')
throw new IllegalStateException();
ins.jump();
final StringBuilder result = new StringBuilder();
while (ins.peek(0) != 0) {
char ch = ins.peek(0);
ins.jump();
if (ch == '{' || ch == '}' || ch == ';')
break;
result.append(ch);
}
return result.toString();
}
private static String readString(CharInspector ins) {
final StringBuilder result = new StringBuilder();
while (ins.peek(0) != 0) {
char ch = ins.peek(0);
if (ch == '\n' || ch == '\r')
break;
if (ch == ' ' && result.charAt(0) != '.')
break;
if (ch == '{' || ch == '}' || ch == ';' || ch == ',' || ch == ':' || ch == '\t')
break;
ins.jump();
// System.err.println("ch=" + ch);
result.append(ch);
}
if (result.charAt(0) == '.')
return result.toString().trim();
return result.toString();
}
} }

View File

@ -0,0 +1,177 @@
/* ========================================================================
* 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.style.parser;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.style.AutomaticCounter;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleLoader;
import net.sourceforge.plantuml.style.StyleScheme;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.style.Value;
import net.sourceforge.plantuml.style.ValueImpl;
import net.sourceforge.plantuml.utils.BlocLines;
import net.sourceforge.plantuml.utils.StringLocated;
public class StyleParserLegacy {
private final static String KEYNAMES = "[-.\\w(), ]+?";
private final static Pattern2 keyName = MyPattern.cmpile("^[:]?(" + KEYNAMES + ")([%s]+\\*)?[%s]*\\{$");
private final static Pattern2 propertyAndValue = MyPattern.cmpile("^([\\w]+):?[%s]+(.*?);?$");
private final static Pattern2 closeBracket = MyPattern.cmpile("^\\}$");
public static Collection<Style> parse(BlocLines lines, AutomaticCounter counter) throws StyleParsingException {
final Collection<Style> foo = StyleParser.parse(lines, counter);
lines = lines.eventuallyMoveAllEmptyBracket();
final List<Style> result = new ArrayList<>();
final CssVariables variables = new CssVariables();
StyleScheme scheme = StyleScheme.REGULAR;
Context context = new Context();
final List<Map<PName, Value>> maps = new ArrayList<Map<PName, Value>>();
boolean inComment = false;
for (StringLocated s : lines) {
String trimmed = s.getTrimmed().getString();
if (trimmed.startsWith("/*") || trimmed.endsWith("*/"))
continue;
if (trimmed.startsWith("/'") || trimmed.endsWith("'/"))
continue;
if (trimmed.startsWith("/*") || trimmed.startsWith("/'")) {
inComment = true;
continue;
}
if (trimmed.endsWith("*/") || trimmed.endsWith("'/")) {
inComment = false;
continue;
}
if (inComment)
continue;
if (trimmed.matches("@media.*dark.*\\{")) {
scheme = StyleScheme.DARK;
continue;
}
if (trimmed.startsWith("--")) {
variables.learn(trimmed);
continue;
}
final int x = trimmed.lastIndexOf("//");
if (x != -1)
trimmed = trimmed.substring(0, x).trim();
final Matcher2 mKeyNames = keyName.matcher(trimmed);
if (mKeyNames.find()) {
String names = mKeyNames.group(1);
final boolean isRecurse = mKeyNames.group(2) != null;
if (isRecurse)
names += "*";
context = context.push(names);
maps.add(new EnumMap<PName, Value>(PName.class));
continue;
}
final Matcher2 mPropertyAndValue = propertyAndValue.matcher(trimmed);
if (mPropertyAndValue.find()) {
final PName key = PName.getFromName(mPropertyAndValue.group(1), scheme);
final String value = variables.value(mPropertyAndValue.group(2));
if (key != null && maps.size() > 0)
maps.get(maps.size() - 1).put(key, //
scheme == StyleScheme.REGULAR ? //
ValueImpl.regular(value, counter) : ValueImpl.dark(value, counter));
continue;
}
final Matcher2 mCloseBracket = closeBracket.matcher(trimmed);
if (mCloseBracket.find()) {
if (context.size() > 0) {
final Collection<StyleSignatureBasic> signatures = context.toSignatures();
for (StyleSignatureBasic signature : signatures) {
Map<PName, Value> tmp = maps.get(maps.size() - 1);
if (signature.isWithDot())
tmp = StyleLoader.addPriorityForStereotype(tmp);
if (tmp.size() > 0) {
final Style style = new Style(signature, tmp);
result.add(style);
}
}
context = context.pop();
maps.remove(maps.size() - 1);
} else {
scheme = StyleScheme.REGULAR;
}
}
}
System.err.println("foo1=" + foo.size());
System.err.println("result=" + result.size());
if (foo.size() != result.size() || foo.size() < 10) {
print_debug(foo);
print_debug(result);
}
// return Collections.unmodifiableList(result);
return Collections.unmodifiableCollection(foo);
}
private static void print_debug(Collection<Style> list) {
System.err.println("=====================");
int i = 0;
for (Style style : list) {
System.err.println("style=" + i + " " + style.getSignature());
i++;
}
System.err.println("=====================");
}
}

View File

@ -0,0 +1,44 @@
/* ========================================================================
* 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.style.parser;
public class StyleParsingException extends Exception {
public StyleParsingException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,61 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.style.parser;
public class StyleToken {
private final StyleTokenType type;
private final String data;
public StyleToken(StyleTokenType type, String data) {
this.type = type;
this.data = data;
}
@Override
public String toString() {
return type.toString() + "[" + data + "]";
}
public final StyleTokenType getType() {
return type;
}
public final String getData() {
return data;
}
}

View File

@ -0,0 +1,48 @@
/* ========================================================================
* 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.style.parser;
enum StyleTokenType {
OPEN_BRACKET, //
CLOSE_BRACKET, //
STRING, //
COMMA, //
STAR, //
NEWLINE, //
SEMICOLON, //
COLON, //
AROBASE_MEDIA, //
}

View File

@ -323,7 +323,17 @@ public final class GeneralImageBuilder {
if (strictUmlStyle) if (strictUmlStyle)
return false; return false;
return entity.isGroup() == false && entity.getLeafType() == LeafType.NOTE && onlyOneLink(entity); if (entity.isGroup())
return false;
if (entity.getLeafType() != LeafType.NOTE)
return false;
final Link single = onlyOneLink(entity);
if (single == null)
return false;
return single.getOther(entity).getLeafType() != LeafType.NOTE;
} }
static class EntityImageSimpleEmpty implements IEntityImage { static class EntityImageSimpleEmpty implements IEntityImage {
@ -482,20 +492,19 @@ public final class GeneralImageBuilder {
return null; return null;
} }
private boolean onlyOneLink(IEntity ent) { private Link onlyOneLink(IEntity ent) {
int nb = 0; Link single = null;
for (Link link : dotData.getLinks()) { for (Link link : dotData.getLinks()) {
if (link.isInvis()) if (link.isInvis())
continue; continue;
if (link.contains(ent) == false)
continue;
if (link.contains(ent)) if (single != null)
nb++; return null;
single = link;
if (nb > 1)
return false;
} }
return nb == 1; return single;
} }
private IEntityImage error(File dotExe) { private IEntityImage error(File dotExe) {
@ -584,7 +593,8 @@ public final class GeneralImageBuilder {
if (g.isRemoved()) if (g.isRemoved())
continue; continue;
if (dotData.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) { if (dotData.isEmpty(g)
&& (g.getGroupType() == GroupType.PACKAGE || g.getGroupType() == GroupType.TOGETHER)) {
final ISkinParam skinParam = dotData.getSkinParam(); final ISkinParam skinParam = dotData.getSkinParam();
final ILeaf folder = entityFactory.createLeafForEmptyGroup(g, skinParam); final ILeaf folder = entityFactory.createLeafForEmptyGroup(g, skinParam);
printEntity(dotStringFactory, folder); printEntity(dotStringFactory, folder);

View File

@ -41,6 +41,7 @@ import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.SkinParamUtils;
import net.sourceforge.plantuml.awt.geom.XDimension2D; import net.sourceforge.plantuml.awt.geom.XDimension2D;
import net.sourceforge.plantuml.baraye.ILeaf; import net.sourceforge.plantuml.baraye.ILeaf;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.EntityPortion; import net.sourceforge.plantuml.cucadiagram.EntityPortion;
import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.LeafType;
@ -95,7 +96,8 @@ public class EntityImageClassHeader extends AbstractEntityImage {
if (displayGenericWithOldFashion && entity.getGeneric() != null) if (displayGenericWithOldFashion && entity.getGeneric() != null)
display = display.addGeneric(entity.getGeneric()); display = display.addGeneric(entity.getGeneric());
TextBlock name = display.createWithNiceCreoleMode(fontConfigurationName, HorizontalAlignment.CENTER, skinParam); TextBlock name = display.create8(fontConfigurationName, HorizontalAlignment.CENTER, skinParam,
CreoleMode.FULL_BUT_UNDERSCORE, style.wrapWidth());
final VisibilityModifier modifier = entity.getVisibilityModifier(); final VisibilityModifier modifier = entity.getVisibilityModifier();
if (modifier == null) { if (modifier == null) {
name = TextBlockUtils.withMargin(name, 3, 3, 0, 0); name = TextBlockUtils.withMargin(name, 3, 3, 0, 0);
@ -127,12 +129,6 @@ public class EntityImageClassHeader extends AbstractEntityImage {
HorizontalAlignment.CENTER, skinParam); HorizontalAlignment.CENTER, skinParam);
genericBlock = TextBlockUtils.withMargin(genericBlock, 1, 1); genericBlock = TextBlockUtils.withMargin(genericBlock, 1, 1);
// final HColor classBackground = SkinParamUtils.getColor(getSkinParam(), stereotype, ColorParam.background);
// final HColor classBorder = SkinParamUtils.getFontColor(getSkinParam(), FontParam.CLASS_STEREOTYPE,
// stereotype);
// final HColor classBackground = style.value(PName.BackGroundColor).asColor(skinParam.getThemeStyle(),
// skinParam.getIHtmlColorSet());
final HColor classBackground = skinParam.getBackgroundColor(); final HColor classBackground = skinParam.getBackgroundColor();
final HColor classBorder = style.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()); final HColor classBorder = style.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());

View File

@ -167,7 +167,7 @@ public class EntityImageDescription extends AbstractEntityImage {
desc = TextBlockUtils.empty(style.value(PName.MinimumWidth).asDouble(), 0); desc = TextBlockUtils.empty(style.value(PName.MinimumWidth).asDouble(), 0);
else else
desc = BodyFactory.create3(entity.getDisplay(), getSkinParam(), defaultAlign, fcTitle, desc = BodyFactory.create3(entity.getDisplay(), getSkinParam(), defaultAlign, fcTitle,
getSkinParam().wrapWidth(), styleTitle); style.wrapWidth(), styleTitle);
stereo = TextBlockUtils.empty(0, 0); stereo = TextBlockUtils.empty(0, 0);

View File

@ -118,7 +118,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
textBlock = new TextBlockEmpty(); textBlock = new TextBlockEmpty();
else else
textBlock = BodyFactory.create3(strings, getSkinParam(), horizontalAlignment, fontConfiguration, textBlock = BodyFactory.create3(strings, getSkinParam(), horizontalAlignment, fontConfiguration,
getSkinParam().wrapWidth(), style); style.wrapWidth(), style);
} }

View File

@ -80,7 +80,7 @@ public class EntityImageState extends EntityImageStateCommon {
.getFontConfiguration(getSkinParam().getIHtmlColorSet()); .getFontConfiguration(getSkinParam().getIHtmlColorSet());
this.fields = list.create8(fieldsFontConfiguration, HorizontalAlignment.LEFT, skinParam, CreoleMode.FULL, this.fields = list.create8(fieldsFontConfiguration, HorizontalAlignment.LEFT, skinParam, CreoleMode.FULL,
skinParam.wrapWidth()); getStyleState().wrapWidth());
} }

View File

@ -72,7 +72,7 @@ public abstract class EntityImageStateCommon extends AbstractEntityImage {
getSkinParam().getIHtmlColorSet(), entity.getColors()); getSkinParam().getIHtmlColorSet(), entity.getColors());
this.title = entity.getDisplay().create8(titleFontConfiguration, HorizontalAlignment.CENTER, skinParam, this.title = entity.getDisplay().create8(titleFontConfiguration, HorizontalAlignment.CENTER, skinParam,
CreoleMode.FULL, skinParam.wrapWidth()); CreoleMode.FULL, getStyleState().wrapWidth());
this.url = entity.getUrl99(); this.url = entity.getUrl99();
} }

View File

@ -177,7 +177,7 @@ public class EntityImageTips extends AbstractEntityImage {
final UStroke stroke = style.getStroke(); final UStroke stroke = style.getStroke();
final TextBlock textBlock = BodyFactory.create3(display, skinParam, HorizontalAlignment.LEFT, fc, final TextBlock textBlock = BodyFactory.create3(display, skinParam, HorizontalAlignment.LEFT, fc,
skinParam.wrapWidth(), style); style.wrapWidth(), style);
return new Opale(shadowing, borderColor, noteBackgroundColor, textBlock, true, stroke); return new Opale(shadowing, borderColor, noteBackgroundColor, textBlock, true, stroke);
} }

View File

@ -369,7 +369,11 @@ public class BlocLines implements Iterable<StringLocated> {
} }
public CharInspector inspector() { public CharInspector inspector() {
return new CharInspectorImpl(this); return new CharInspectorImpl(this, false);
}
public CharInspector inspectorWithNewlines() {
return new CharInspectorImpl(this, true);
} }
} }

View File

@ -38,5 +38,5 @@ package net.sourceforge.plantuml.utils;
public interface CharInspector { public interface CharInspector {
char peek(int ahead); char peek(int ahead);
void next(); void jump();
} }

View File

@ -38,11 +38,13 @@ package net.sourceforge.plantuml.utils;
public class CharInspectorImpl implements CharInspector { public class CharInspectorImpl implements CharInspector {
final private BlocLines data; final private BlocLines data;
final private boolean insertNewlines;
private int line = 0; private int line = 0;
private int pos = 0; private int pos = 0;
CharInspectorImpl(BlocLines input) { CharInspectorImpl(BlocLines input, boolean insertNewlines) {
data = input; this.data = input;
this.insertNewlines = insertNewlines;
} }
@Override @Override
@ -56,11 +58,13 @@ public class CharInspectorImpl implements CharInspector {
} }
private String getCurrentLine() { private String getCurrentLine() {
if (insertNewlines)
return data.getAt(line).getTrimmed().getString() + "\n";
return data.getAt(line).getTrimmed().getString(); return data.getAt(line).getTrimmed().getString();
} }
@Override @Override
public void next() { public void jump() {
if (line == -1) if (line == -1)
throw new IllegalStateException(); throw new IllegalStateException();
pos++; pos++;

View File

@ -0,0 +1,42 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.utils;
public interface Inspector<O> {
O peek(int ahead);
void jump();
}

View File

@ -0,0 +1,65 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, 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.utils;
import java.util.List;
public abstract class InspectorUtils {
private InspectorUtils() {
}
public static <O> Inspector<O> inspector(final List<O> list) {
return new Inspector<O>() {
private int pos = 0;
@Override
public O peek(int ahead) {
final int tmp = pos + ahead;
if (tmp < list.size())
return list.get(tmp);
return null;
}
@Override
public void jump() {
pos++;
}
};
}
}

View File

@ -45,7 +45,7 @@ public class Version {
private static final int MAJOR_SEPARATOR = 1000000; private static final int MAJOR_SEPARATOR = 1000000;
public static int version() { public static int version() {
return 1202214; return 1202300;
} }
public static int versionPatched() { public static int versionPatched() {
@ -81,7 +81,7 @@ public class Version {
} }
public static int beta() { public static int beta() {
final int beta = 6; final int beta = 0;
return beta; return beta;
} }
@ -94,7 +94,7 @@ public class Version {
} }
public static long compileTime() { public static long compileTime() {
return 1670351053526L; return 1673289094677L;
} }
public static String compileTimeString() { public static String compileTimeString() {

View File

@ -57,9 +57,9 @@ public final class WindowsDotArchive {
} }
public final synchronized static WindowsDotArchive getInstance() { public final synchronized static WindowsDotArchive getInstance() {
if (singleton == null) { if (singleton == null)
singleton = new WindowsDotArchive(); singleton = new WindowsDotArchive();
}
return singleton; return singleton;
} }
@ -92,11 +92,16 @@ public final class WindowsDotArchive {
if (name.length() == 0) if (name.length() == 0)
break; break;
final int size = readNumber(is); final int size = readNumber(is);
try (final OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dir, name)))) { final File fileout = new File(dir, name);
for (int i = 0; i < size; i++) {
fos.write(is.read()); if (fileout.exists())
for (int i = 0; i < size; i++)
is.read();
else
try (final OutputStream fos = new BufferedOutputStream(new FileOutputStream(fileout))) {
for (int i = 0; i < size; i++)
fos.write(is.read());
} }
}
} }
} }
} }
@ -112,18 +117,19 @@ public final class WindowsDotArchive {
} }
public synchronized File getWindowsExeLite() { public synchronized File getWindowsExeLite() {
if (isThereArchive() == false) { if (isThereArchive() == false)
return null; return null;
}
if (exe == null) if (exe == null) {
final File tmp = new File(System.getProperty("java.io.tmpdir"), "_graphviz");
try { try {
final File tmp = new File(System.getProperty("java.io.tmpdir"), "_graphviz");
tmp.mkdirs(); tmp.mkdirs();
extract(tmp); extract(tmp);
exe = new File(tmp, "dot.exe");
} catch (IOException e) { } catch (IOException e) {
Logme.error(e); Logme.error(e);
} }
exe = new File(tmp, "dot.exe");
}
return exe; return exe;
} }

View File

@ -0,0 +1,107 @@
/* ========================================================================
* 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.yaml;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
public class Highlighted {
public static final String HIGHLIGHTED = "#highlight ";
private final static Pattern pattern = Pattern.compile("^([^<>]+)(\\<\\<.*\\>\\>)?$");
private final List<String> paths;
private final Stereotype stereotype;
private Highlighted(List<String> paths, Stereotype stereotype) {
this.paths = paths;
this.stereotype = stereotype;
}
public static boolean matchesDefinition(String line) {
return line.startsWith(Highlighted.HIGHLIGHTED);
}
public static Highlighted build(String line) {
if (matchesDefinition(line) == false)
throw new IllegalStateException();
line = line.substring(HIGHLIGHTED.length()).trim();
final Matcher matcher = pattern.matcher(line);
if (matcher.matches() == false)
throw new IllegalStateException();
final String paths = matcher.group(1).trim();
final Stereotype stereotype = matcher.group(2) == null ? null : Stereotype.build(matcher.group(2));
return new Highlighted(toList(paths), stereotype);
}
private static List<String> toList(String paths) {
final List<String> result = new ArrayList<>();
for (String s : paths.split("/"))
result.add(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(s.trim(), "\""));
return result;
}
public Highlighted upOneLevel(String key) {
if (paths.size() <= 1)
return null;
final String first = paths.get(0);
if ("**".equals(first))
return new Highlighted(paths, stereotype);
if ("*".equals(first) || first.equals(key))
return new Highlighted(paths.subList(1, paths.size()), stereotype);
return null;
}
public boolean isKeyHighlight(String key) {
if (paths.size() == 2 && paths.get(0).equals("**") && paths.get(1).equals(key))
return true;
return paths.size() == 1 && paths.get(0).equals(key);
}
public final Stereotype getStereotype() {
return stereotype;
}
}

View File

@ -53,6 +53,7 @@ import net.sourceforge.plantuml.json.JsonValue;
import net.sourceforge.plantuml.jsondiagram.JsonDiagram; import net.sourceforge.plantuml.jsondiagram.JsonDiagram;
import net.sourceforge.plantuml.jsondiagram.StyleExtractor; import net.sourceforge.plantuml.jsondiagram.StyleExtractor;
import net.sourceforge.plantuml.log.Logme; import net.sourceforge.plantuml.log.Logme;
import net.sourceforge.plantuml.style.parser.StyleParsingException;
public class YamlDiagramFactory extends PSystemAbstractFactory { public class YamlDiagramFactory extends PSystemAbstractFactory {
@ -62,7 +63,7 @@ public class YamlDiagramFactory extends PSystemAbstractFactory {
@Override @Override
public Diagram createSystem(UmlSource source, Map<String, String> skinParam) { public Diagram createSystem(UmlSource source, Map<String, String> skinParam) {
final List<String> highlighted = new ArrayList<>(); final List<Highlighted> highlighted = new ArrayList<>();
JsonValue yaml = null; JsonValue yaml = null;
StyleExtractor styleExtractor = null; StyleExtractor styleExtractor = null;
try { try {
@ -75,8 +76,8 @@ public class YamlDiagramFactory extends PSystemAbstractFactory {
if (it.hasNext() == false) if (it.hasNext() == false)
break; break;
if (line.startsWith("#highlight ")) { if (Highlighted.matchesDefinition(line)) {
highlighted.add(line.substring("#highlight ".length()).trim()); highlighted.add(Highlighted.build(line));
continue; continue;
} }
list.add(line); list.add(line);
@ -87,7 +88,11 @@ public class YamlDiagramFactory extends PSystemAbstractFactory {
} }
final JsonDiagram result = new JsonDiagram(source, UmlDiagramType.YAML, yaml, highlighted, styleExtractor); final JsonDiagram result = new JsonDiagram(source, UmlDiagramType.YAML, yaml, highlighted, styleExtractor);
if (styleExtractor != null) { if (styleExtractor != null) {
styleExtractor.applyStyles(result.getSkinParam()); try {
styleExtractor.applyStyles(result.getSkinParam());
} catch (StyleParsingException e) {
Logme.error(e);
}
final String title = styleExtractor.getTitle(); final String title = styleExtractor.getTitle();
if (title != null) if (title != null)
result.setTitle(DisplayPositioned.single(Display.getWithNewlines(title), HorizontalAlignment.CENTER, result.setTitle(DisplayPositioned.single(Display.getWithNewlines(title), HorizontalAlignment.CENTER,

Binary file not shown.

Binary file not shown.

View File

@ -258,10 +258,6 @@ class SkinParamTest {
assertThat(skinParam.useSwimlanes(umlDiagramType)).isFalse(); assertThat(skinParam.useSwimlanes(umlDiagramType)).isFalse();
assertThat(skinParam.useUnderlineForHyperlink()).isNotNull(); assertThat(skinParam.useUnderlineForHyperlink()).isNotNull();
final LineBreakStrategy wrapWidth = skinParam.wrapWidth();
assertThat(wrapWidth.isAuto()).isFalse();
assertThat(wrapWidth.getMaxWidth()).isZero();
} }
@Test @Test