mirror of
https://github.com/octoleo/plantuml.git
synced 2024-11-21 12:35:10 +00:00
Import version 1.2021.0
This commit is contained in:
parent
3a7e935cec
commit
5ec1037202
@ -83,6 +83,7 @@
|
||||
<mkdir dir="dist" />
|
||||
<jar jarfile="plantuml.jar" basedir="build">
|
||||
<manifest>
|
||||
<attribute name="Automatic-Module-Name" value="net.sourceforge.plantuml" />
|
||||
<attribute name="Main-Class" value="net.sourceforge.plantuml.Run" />
|
||||
<attribute name="Class-Path" value="avalon-framework-4.2.0.jar batik-all-1.7.jar commons-io-1.3.1.jar commons-logging-1.0.4.jar fop.jar xml-apis-ext-1.3.04.jar xmlgraphics-commons-1.4.jar jlatexmath-minimal-1.0.3.jar jlm_cyrillic.jar jlm_greek.jar vizjs.jar j2v8_win32_x86_64-3.1.6.jar j2v8_linux_x86_64-3.1.6.jar j2v8_macosx_x86_64-3.1.6.jar ditaa0_9.jar" />
|
||||
</manifest>
|
||||
|
2
pom.xml
2
pom.xml
@ -35,7 +35,7 @@
|
||||
|
||||
<groupId>net.sourceforge.plantuml</groupId>
|
||||
<artifactId>plantuml</artifactId>
|
||||
<version>1.2020.27-SNAPSHOT</version>
|
||||
<version>1.2021.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>PlantUML</name>
|
||||
|
@ -46,7 +46,9 @@ import java.io.IOException;
|
||||
|
||||
import net.sourceforge.plantuml.braille.BrailleCharFactory;
|
||||
import net.sourceforge.plantuml.braille.UGraphicBraille;
|
||||
import net.sourceforge.plantuml.graphic.FontStyle;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.StyledString;
|
||||
import net.sourceforge.plantuml.png.MetadataTag;
|
||||
import net.sourceforge.plantuml.security.SFile;
|
||||
import net.sourceforge.plantuml.svg.SvgGraphics;
|
||||
@ -142,10 +144,20 @@ public enum FileFormat {
|
||||
}
|
||||
|
||||
static private Dimension2DDouble getJavaDimension(UFont font, String text) {
|
||||
final Font javaFont = font.getFont();
|
||||
final FontMetrics fm = gg.getFontMetrics(javaFont);
|
||||
final Rectangle2D rect = fm.getStringBounds(text, gg);
|
||||
return new Dimension2DDouble(rect.getWidth(), rect.getHeight());
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
for (StyledString styledString : StyledString.build(text)) {
|
||||
final Font javaFont;
|
||||
if (styledString.getStyle() == FontStyle.BOLD)
|
||||
javaFont = font.bold().getFont();
|
||||
else
|
||||
javaFont = font.getFont();
|
||||
final FontMetrics fm = gg.getFontMetrics(javaFont);
|
||||
final Rectangle2D rect = fm.getStringBounds(styledString.getText(), gg);
|
||||
width += rect.getWidth();
|
||||
height = Math.max(height, rect.getHeight());
|
||||
}
|
||||
return new Dimension2DDouble(width, height);
|
||||
}
|
||||
|
||||
private StringBounder getBrailleStringBounder() {
|
||||
|
@ -51,6 +51,7 @@ import net.sourceforge.plantuml.style.StyleBuilder;
|
||||
import net.sourceforge.plantuml.svek.ConditionEndStyle;
|
||||
import net.sourceforge.plantuml.svek.ConditionStyle;
|
||||
import net.sourceforge.plantuml.svek.PackageStyle;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
@ -189,5 +190,8 @@ public interface ISkinParam extends ISkinSimple {
|
||||
public ActorStyle actorStyle();
|
||||
|
||||
public void setSvgSize(String origin, String sizeToUse);
|
||||
|
||||
public LengthAdjust getlengthAdjust();
|
||||
|
||||
|
||||
}
|
@ -97,6 +97,7 @@ import net.sourceforge.plantuml.version.PSystemLicenseFactory;
|
||||
import net.sourceforge.plantuml.version.PSystemVersionFactory;
|
||||
import net.sourceforge.plantuml.wbs.WBSDiagramFactory;
|
||||
import net.sourceforge.plantuml.wire.WireDiagramFactory;
|
||||
import net.sourceforge.plantuml.yaml.YamlDiagramFactory;
|
||||
|
||||
public class PSystemBuilder {
|
||||
|
||||
@ -217,6 +218,7 @@ public class PSystemBuilder {
|
||||
factories.add(new JsonDiagramFactory());
|
||||
factories.add(new GitDiagramFactory());
|
||||
factories.add(new BoardDiagramFactory());
|
||||
factories.add(new YamlDiagramFactory());
|
||||
return factories;
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ import net.sourceforge.plantuml.style.StyleLoader;
|
||||
import net.sourceforge.plantuml.svek.ConditionEndStyle;
|
||||
import net.sourceforge.plantuml.svek.ConditionStyle;
|
||||
import net.sourceforge.plantuml.svek.PackageStyle;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
@ -113,6 +114,9 @@ public class SkinParam implements ISkinParam {
|
||||
if (type == UmlDiagramType.BOARD) {
|
||||
UseStyle.setBetaStyle(true);
|
||||
}
|
||||
if (type == UmlDiagramType.YAML) {
|
||||
UseStyle.setBetaStyle(true);
|
||||
}
|
||||
if (type == UmlDiagramType.SEQUENCE) {
|
||||
// skin = "debug.skin";
|
||||
// USE_STYLE2.set(true);
|
||||
@ -1258,4 +1262,18 @@ public class SkinParam implements ISkinParam {
|
||||
return s;
|
||||
}
|
||||
|
||||
public LengthAdjust getlengthAdjust() {
|
||||
final String value = getValue("lengthAdjust");
|
||||
if ("spacingAndGlyphs".equalsIgnoreCase(value)) {
|
||||
return LengthAdjust.SPACING_AND_GLYPHS;
|
||||
}
|
||||
if ("spacing".equalsIgnoreCase(value)) {
|
||||
return LengthAdjust.SPACING;
|
||||
}
|
||||
if ("none".equalsIgnoreCase(value)) {
|
||||
return LengthAdjust.NONE;
|
||||
}
|
||||
return LengthAdjust.defaultValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ import net.sourceforge.plantuml.style.StyleBuilder;
|
||||
import net.sourceforge.plantuml.svek.ConditionEndStyle;
|
||||
import net.sourceforge.plantuml.svek.ConditionStyle;
|
||||
import net.sourceforge.plantuml.svek.PackageStyle;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
@ -372,4 +373,8 @@ public class SkinParamDelegator implements ISkinParam {
|
||||
return skinParam.transformStringForSizeHack(s);
|
||||
}
|
||||
|
||||
public LengthAdjust getlengthAdjust() {
|
||||
return skinParam.getlengthAdjust();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -68,6 +68,9 @@ public class StringUtils {
|
||||
public static final char PACKAGE_PRIVATE_METHOD = '\uEEF5';
|
||||
public static final char PUBLIC_METHOD = '\uEEF4';
|
||||
public static final char IE_MANDATORY = '\uEEF3';
|
||||
|
||||
public static final char BOLD_START = '\uEEF2';
|
||||
public static final char BOLD_END = '\uEEF1';
|
||||
|
||||
// Used in BackSlash
|
||||
public static final char PRIVATE_BLOCK = '\uE000';
|
||||
|
@ -58,6 +58,7 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
|
||||
private final DisplaySection header = DisplaySection.none();
|
||||
private final DisplaySection footer = DisplaySection.none();
|
||||
private Display mainFrame;
|
||||
private final UmlDiagramType type;
|
||||
|
||||
private final SkinParam skinParam;
|
||||
|
||||
@ -67,22 +68,25 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
|
||||
return pragma;
|
||||
}
|
||||
|
||||
public TitledDiagram() {
|
||||
this.skinParam = SkinParam.create(getUmlDiagramType());
|
||||
public TitledDiagram(UmlDiagramType type) {
|
||||
this.type = type;
|
||||
this.skinParam = SkinParam.create(type);
|
||||
}
|
||||
|
||||
public final StyleBuilder getCurrentStyleBuilder() {
|
||||
return skinParam.getCurrentStyleBuilder();
|
||||
}
|
||||
|
||||
public TitledDiagram(ISkinSimple orig) {
|
||||
this();
|
||||
public TitledDiagram(UmlDiagramType type, ISkinSimple orig) {
|
||||
this(type);
|
||||
if (orig != null) {
|
||||
this.skinParam.copyAllFrom(orig);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public UmlDiagramType getUmlDiagramType();
|
||||
final public UmlDiagramType getUmlDiagramType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public final ISkinParam getSkinParam() {
|
||||
return skinParam;
|
||||
|
@ -98,12 +98,12 @@ public abstract class UmlDiagram extends TitledDiagram implements Diagram, Annot
|
||||
|
||||
private Animation animation;
|
||||
|
||||
public UmlDiagram() {
|
||||
super();
|
||||
public UmlDiagram(UmlDiagramType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
public UmlDiagram(ISkinSimple orig) {
|
||||
super(orig);
|
||||
public UmlDiagram(UmlDiagramType type, ISkinSimple orig) {
|
||||
super(type, orig);
|
||||
}
|
||||
|
||||
final public int getMinwidth() {
|
||||
|
@ -39,7 +39,7 @@ import net.sourceforge.plantuml.style.SName;
|
||||
|
||||
public enum UmlDiagramType {
|
||||
SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, WIRE,
|
||||
HELP, GANTT, SALT, JSON, GIT, BOARD;
|
||||
HELP, GANTT, SALT, JSON, GIT, BOARD, YAML;
|
||||
|
||||
public SName getStyleName() {
|
||||
if (this == SEQUENCE) {
|
||||
|
@ -61,7 +61,7 @@ public class ActivityDiagram extends CucaDiagram {
|
||||
private ConditionalContext currentContext;
|
||||
|
||||
public ActivityDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.ACTIVITY, skinParam);
|
||||
setNamespaceSeparator(null);
|
||||
}
|
||||
|
||||
@ -163,11 +163,6 @@ public class ActivityDiagram extends CucaDiagram {
|
||||
return lastEntityBrancheConsulted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.ACTIVITY;
|
||||
}
|
||||
|
||||
public final ConditionalContext getCurrentContext() {
|
||||
return currentContext;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public class ActivityDiagram3 extends UmlDiagram {
|
||||
private final Swimlanes swinlanes = new Swimlanes(getSkinParam(), getPragma());
|
||||
|
||||
public ActivityDiagram3(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.ACTIVITY, skinParam);
|
||||
}
|
||||
|
||||
private void manageSwimlaneStrategy() {
|
||||
@ -199,11 +199,6 @@ public class ActivityDiagram3 extends UmlDiagram {
|
||||
return new DiagramDescription("activity3");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.ACTIVITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
|
||||
throws IOException {
|
||||
|
@ -47,6 +47,7 @@ import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UShape;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
|
||||
public class UGraphicInterceptorUDrawable2 extends UGraphicDelegator {
|
||||
@ -85,10 +86,11 @@ public class UGraphicInterceptorUDrawable2 extends UGraphicDelegator {
|
||||
}
|
||||
|
||||
private void drawGoto(FtileGoto ftile) {
|
||||
final HColor gotoColor = HColorUtils.MY_RED;
|
||||
|
||||
final FtileGeometry geom = ftile.calculateDimension(getStringBounder());
|
||||
final Point2D pt = geom.getPointIn();
|
||||
UGraphic ugGoto = getUg().apply(HColorUtils.GREEN).apply(
|
||||
HColorUtils.GREEN.bg());
|
||||
UGraphic ugGoto = getUg().apply(gotoColor).apply(gotoColor.bg());
|
||||
ugGoto = ugGoto.apply(new UTranslate(pt));
|
||||
final UTranslate posNow = getPosition();
|
||||
final UTranslate dest = positions.get(ftile.getName());
|
||||
|
@ -80,9 +80,8 @@ public class BoardDiagram extends UmlDiagram {
|
||||
return new DiagramDescription("Board");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.BOARD;
|
||||
public BoardDiagram() {
|
||||
super(UmlDiagramType.BOARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,9 +78,8 @@ public class BpmDiagram extends UmlDiagram {
|
||||
return new DiagramDescription("(Bpm Diagram)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.BPM;
|
||||
public BpmDiagram() {
|
||||
super(UmlDiagramType.BPM);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,13 +41,14 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinSimple;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.core.DiagramDescription;
|
||||
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
|
||||
|
||||
public abstract class AbstractEntityDiagram extends CucaDiagram {
|
||||
|
||||
public AbstractEntityDiagram(ISkinSimple orig) {
|
||||
super(orig);
|
||||
public AbstractEntityDiagram(UmlDiagramType type, ISkinSimple orig) {
|
||||
super(type, orig);
|
||||
}
|
||||
|
||||
final protected List<String> getDotStrings() {
|
||||
|
@ -67,7 +67,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
|
||||
public ClassDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.CLASS, skinParam);
|
||||
}
|
||||
|
||||
private Code getShortName1972(Code code) {
|
||||
@ -170,11 +170,6 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
return super.leafExist(getFullyQualifiedCode1972(code));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.CLASS;
|
||||
}
|
||||
|
||||
private boolean allowMixing;
|
||||
|
||||
public void setAllowMixing(boolean allowMixing) {
|
||||
|
@ -40,6 +40,7 @@ import net.sourceforge.plantuml.TitledDiagram;
|
||||
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.RegexOr;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
|
||||
@ -57,13 +58,16 @@ public class CommandCaption extends SingleLineCommand2<TitledDiagram> {
|
||||
RegexLeaf.start(), //
|
||||
new RegexLeaf("caption"), //
|
||||
new RegexLeaf("(?:[%s]*:[%s]*|[%s]+)"), //
|
||||
new RegexLeaf("DISPLAY", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("DISPLAY1", "[%g](.*)[%g]"), //
|
||||
new RegexLeaf("DISPLAY2", "(.*[\\p{L}0-9_.].*)")), //
|
||||
RegexLeaf.end()); //
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutionResult executeArg(TitledDiagram diagram, LineLocation location, RegexResult arg) {
|
||||
diagram.setCaption(DisplayPositionned.single(Display.getWithNewlines(arg.get("DISPLAY", 0)),
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM));
|
||||
final Display s = Display.getWithNewlines(arg.getLazzy("DISPLAY", 0));
|
||||
diagram.setCaption(DisplayPositionned.single(s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,10 @@ public class CommandFooter extends SingleLineCommand2<TitledDiagram> {
|
||||
new RegexOr( //
|
||||
new RegexConcat(RegexLeaf.spaceZeroOrMore(), new RegexLeaf(":"), RegexLeaf.spaceZeroOrMore()), //
|
||||
RegexLeaf.spaceOneOrMore()), //
|
||||
new RegexLeaf("LABEL", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("LABEL1", "[%g](.*)[%g]"), //
|
||||
new RegexLeaf("LABEL2", "(.*[\\p{L}0-9_.].*)")), //
|
||||
RegexLeaf.end()); //
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,7 +77,8 @@ public class CommandFooter extends SingleLineCommand2<TitledDiagram> {
|
||||
ha = FontParam.FOOTER.getStyleDefinition(null).getMergedStyle(diagram.getCurrentStyleBuilder())
|
||||
.getHorizontalAlignment();
|
||||
}
|
||||
diagram.getFooter().putDisplay(Display.getWithNewlines(arg.get("LABEL", 0)), ha);
|
||||
final Display s = Display.getWithNewlines(arg.getLazzy("LABEL", 0));
|
||||
diagram.getFooter().putDisplay(s, ha);
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
@ -65,7 +65,10 @@ public class CommandHeader extends SingleLineCommand2<TitledDiagram> {
|
||||
new RegexLeaf(":"), //
|
||||
RegexLeaf.spaceZeroOrMore()), //
|
||||
RegexLeaf.spaceOneOrMore()), //
|
||||
new RegexLeaf("LABEL", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("LABEL1", "[%g](.*)[%g]"), //
|
||||
new RegexLeaf("LABEL2", "(.*[\\p{L}0-9_.].*)")), //
|
||||
RegexLeaf.end()); //
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,7 +79,8 @@ public class CommandHeader extends SingleLineCommand2<TitledDiagram> {
|
||||
ha = FontParam.HEADER.getStyleDefinition(null).getMergedStyle(diagram.getCurrentStyleBuilder())
|
||||
.getHorizontalAlignment();
|
||||
}
|
||||
diagram.getHeader().putDisplay(Display.getWithNewlines(arg.get("LABEL", 0)), ha);
|
||||
final Display s = Display.getWithNewlines(arg.getLazzy("LABEL", 0));
|
||||
diagram.getHeader().putDisplay(s, ha);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
}
|
||||
|
73
src/net/sourceforge/plantuml/command/CommandLegend.java
Normal file
73
src/net/sourceforge/plantuml/command/CommandLegend.java
Normal file
@ -0,0 +1,73 @@
|
||||
/* ========================================================================
|
||||
* 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.command;
|
||||
|
||||
import net.sourceforge.plantuml.LineLocation;
|
||||
import net.sourceforge.plantuml.TitledDiagram;
|
||||
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.RegexOr;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.VerticalAlignment;
|
||||
|
||||
public class CommandLegend extends SingleLineCommand2<TitledDiagram> {
|
||||
|
||||
public CommandLegend() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandLegend.class.getName(), //
|
||||
RegexLeaf.start(), //
|
||||
new RegexLeaf("legend"), //
|
||||
new RegexLeaf("(?:[%s]*:[%s]*|[%s]+)"), //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("LEGEND1", "[%g](.*)[%g]"), //
|
||||
new RegexLeaf("LEGEND2", "(.*[\\p{L}0-9_.].*)")), //
|
||||
RegexLeaf.end()); //
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutionResult executeArg(TitledDiagram diagram, LineLocation location, RegexResult arg) {
|
||||
final Display s = Display.getWithNewlines(arg.getLazzy("LEGEND", 0));
|
||||
diagram.setLegend(DisplayPositionned.single(s, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ import net.sourceforge.plantuml.TitledDiagram;
|
||||
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.RegexOr;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
|
||||
@ -57,13 +58,16 @@ public class CommandTitle extends SingleLineCommand2<TitledDiagram> {
|
||||
RegexLeaf.start(), //
|
||||
new RegexLeaf("title"), //
|
||||
new RegexLeaf("(?:[%s]*:[%s]*|[%s]+)"), //
|
||||
new RegexLeaf("TITLE", "(.*[\\p{L}0-9_.].*)"), RegexLeaf.end()); //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("TITLE1", "[%g](.*)[%g]"), //
|
||||
new RegexLeaf("TITLE2", "(.*[\\p{L}0-9_.].*)")), //
|
||||
RegexLeaf.end()); //
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutionResult executeArg(TitledDiagram diagram, LineLocation location, RegexResult arg) {
|
||||
diagram.setTitle(DisplayPositionned.single(Display.getWithNewlines(arg.get("TITLE", 0)),
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.TOP));
|
||||
final Display s = Display.getWithNewlines(arg.getLazzy("TITLE", 0));
|
||||
diagram.setTitle(DisplayPositionned.single(s, HorizontalAlignment.CENTER, VerticalAlignment.TOP));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
}
|
||||
|
@ -262,6 +262,7 @@ public abstract class PSystemCommandFactory extends PSystemAbstractFactory {
|
||||
cmds.add(new CommandMultilinesCaption());
|
||||
cmds.add(new CommandMultilinesTitle());
|
||||
cmds.add(new CommandMultilinesLegend());
|
||||
cmds.add(new CommandLegend());
|
||||
|
||||
cmds.add(new CommandFooter());
|
||||
cmds.add(new CommandMultilinesFooter());
|
||||
|
@ -47,7 +47,7 @@ import net.sourceforge.plantuml.graphic.USymbol;
|
||||
public class CompositeDiagram extends AbstractEntityDiagram {
|
||||
|
||||
public CompositeDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.COMPOSITE, skinParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -63,9 +63,4 @@ public class CompositeDiagram extends AbstractEntityDiagram {
|
||||
return getOrCreateLeafDefault(ident, code, type, symbol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.COMPOSITE;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ import net.sourceforge.plantuml.utils.StartUtils;
|
||||
|
||||
public enum DiagramType {
|
||||
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX,
|
||||
DEFINITION, GANTT, NW, MINDMAP, WBS, WIRE, JSON, GIT, BOARD,
|
||||
DEFINITION, GANTT, NW, MINDMAP, WBS, WIRE, JSON, GIT, BOARD, YAML,
|
||||
UNKNOWN;
|
||||
|
||||
static public DiagramType getTypeFromArobaseStart(String s) {
|
||||
@ -113,6 +113,9 @@ public enum DiagramType {
|
||||
if (StartUtils.startsWithSymbolAnd("startboard", s)) {
|
||||
return BOARD;
|
||||
}
|
||||
if (StartUtils.startsWithSymbolAnd("startyaml", s)) {
|
||||
return YAML;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class CommandCreoleStyle implements Command {
|
||||
private final FontStyle style;
|
||||
private final boolean tryExtendedColor;
|
||||
|
||||
public static CommandCreoleStyle createCreole(FontStyle style) {
|
||||
public static Command createCreole(FontStyle style) {
|
||||
return new CommandCreoleStyle("^(" + style.getCreoleSyntax() + "(.+?)" + style.getCreoleSyntax() + ")", style,
|
||||
false);
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
/* ========================================================================
|
||||
* 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.creole.command;
|
||||
|
||||
import net.sourceforge.plantuml.StringUtils;
|
||||
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.creole.legacy.StripeSimple;
|
||||
import net.sourceforge.plantuml.graphic.FontStyle;
|
||||
|
||||
public class CommandCreoleStyle2 implements Command {
|
||||
|
||||
private final Pattern2 p;
|
||||
private final FontStyle style;
|
||||
|
||||
public static Command createCreole(FontStyle style) {
|
||||
return new CommandCreoleStyle2("^(" + style.getCreoleSyntax() + "(.+?)" + style.getCreoleSyntax() + ")", style);
|
||||
}
|
||||
|
||||
public static Command createLegacy(FontStyle style) {
|
||||
return new CommandCreoleStyle2(
|
||||
"^((" + style.getActivationPattern() + ")(.+?)" + style.getDeactivationPattern() + ")", style);
|
||||
}
|
||||
|
||||
public static Command createLegacyEol(FontStyle style) {
|
||||
return new CommandCreoleStyle2("^((" + style.getActivationPattern() + ")(.+))$", style);
|
||||
}
|
||||
|
||||
private CommandCreoleStyle2(String p, FontStyle style) {
|
||||
this.p = MyPattern.cmpile(p);
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public String executeAndGetRemaining(final String line, StripeSimple stripe) {
|
||||
final Matcher2 m = p.matcher(line);
|
||||
if (m.find() == false) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
final int groupCount = m.groupCount();
|
||||
final String part1 = m.group(groupCount);
|
||||
final String part2 = line.substring(m.group(1).length());
|
||||
return StringUtils.BOLD_START + part1 + StringUtils.BOLD_END + part2;
|
||||
|
||||
}
|
||||
|
||||
public int matchingSize(String line) {
|
||||
final Matcher2 m = p.matcher(line);
|
||||
if (m.find() == false) {
|
||||
return 0;
|
||||
}
|
||||
return m.group(1).length();
|
||||
}
|
||||
|
||||
}
|
@ -69,6 +69,7 @@ import net.sourceforge.plantuml.creole.command.CommandCreoleSizeChange;
|
||||
import net.sourceforge.plantuml.creole.command.CommandCreoleSpace;
|
||||
import net.sourceforge.plantuml.creole.command.CommandCreoleSprite;
|
||||
import net.sourceforge.plantuml.creole.command.CommandCreoleStyle;
|
||||
import net.sourceforge.plantuml.creole.command.CommandCreoleStyle2;
|
||||
import net.sourceforge.plantuml.creole.command.CommandCreoleSvgAttributeChange;
|
||||
import net.sourceforge.plantuml.creole.command.CommandCreoleUrl;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
@ -113,6 +114,8 @@ public class StripeSimple implements Stripe {
|
||||
return header;
|
||||
}
|
||||
|
||||
public final static boolean TSPAN = false;
|
||||
|
||||
public StripeSimple(FontConfiguration fontConfiguration, StripeStyle style, CreoleContext context,
|
||||
ISkinSimple skinParam, CreoleMode modeSimpleLine) {
|
||||
this.fontConfiguration = fontConfiguration;
|
||||
@ -120,9 +123,16 @@ public class StripeSimple implements Stripe {
|
||||
this.skinParam = skinParam;
|
||||
|
||||
// class Splitter
|
||||
this.commands.add(CommandCreoleStyle.createCreole(FontStyle.BOLD));
|
||||
this.commands.add(CommandCreoleStyle.createLegacy(FontStyle.BOLD));
|
||||
this.commands.add(CommandCreoleStyle.createLegacyEol(FontStyle.BOLD));
|
||||
if (TSPAN) {
|
||||
this.commands.add(CommandCreoleStyle2.createCreole(FontStyle.BOLD));
|
||||
this.commands.add(CommandCreoleStyle2.createLegacy(FontStyle.BOLD));
|
||||
this.commands.add(CommandCreoleStyle2.createLegacyEol(FontStyle.BOLD));
|
||||
} else {
|
||||
this.commands.add(CommandCreoleStyle.createCreole(FontStyle.BOLD));
|
||||
this.commands.add(CommandCreoleStyle.createLegacy(FontStyle.BOLD));
|
||||
this.commands.add(CommandCreoleStyle.createLegacyEol(FontStyle.BOLD));
|
||||
}
|
||||
|
||||
this.commands.add(CommandCreoleStyle.createCreole(FontStyle.ITALIC));
|
||||
this.commands.add(CommandCreoleStyle.createLegacy(FontStyle.ITALIC));
|
||||
this.commands.add(CommandCreoleStyle.createLegacyEol(FontStyle.ITALIC));
|
||||
|
@ -118,8 +118,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
|
||||
return ident;
|
||||
}
|
||||
|
||||
public CucaDiagram(ISkinSimple orig) {
|
||||
super(orig);
|
||||
public CucaDiagram(UmlDiagramType type, ISkinSimple orig) {
|
||||
super(type, orig);
|
||||
this.stacks2.add(Ident.empty());
|
||||
}
|
||||
|
||||
|
@ -77,10 +77,14 @@ abstract class AbstractGraphviz implements Graphviz {
|
||||
this.dotString = dotString;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
protected boolean findExecutableOnPath() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected File searchDotExe() {
|
||||
final protected File searchDotExe() {
|
||||
String getenv = GraphvizUtils.getenvGraphvizDot();
|
||||
if (getenv == null) {
|
||||
if (findExecutableOnPath() && getenv == null) {
|
||||
getenv = findExecutableOnPath(getExeName());
|
||||
}
|
||||
if (getenv == null) {
|
||||
|
@ -46,8 +46,8 @@ class GraphvizWindowsLite extends AbstractGraphviz {
|
||||
static private File specificDotExe;
|
||||
|
||||
@Override
|
||||
protected File searchDotExe() {
|
||||
return specificDotExe();
|
||||
protected boolean findExecutableOnPath() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,7 +48,7 @@ import net.sourceforge.plantuml.graphic.USymbol;
|
||||
public class DescriptionDiagram extends AbstractEntityDiagram {
|
||||
|
||||
public DescriptionDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.DESCRIPTION, skinParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,7 +74,7 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
|
||||
if (type == null) {
|
||||
String codeString = code.getName();
|
||||
if (codeString.startsWith("[") && codeString.endsWith("]")) {
|
||||
final USymbol sym = getSkinParam().componentStyle().toUSymbol() ;
|
||||
final USymbol sym = getSkinParam().componentStyle().toUSymbol();
|
||||
final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:");
|
||||
return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION, sym);
|
||||
}
|
||||
@ -127,9 +127,4 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
|
||||
return super.checkFinalError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.DESCRIPTION;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -87,9 +87,8 @@ public class FlowDiagram extends UmlDiagram implements TextBlock {
|
||||
return new DiagramDescription("Flow Diagram");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.FLOW;
|
||||
public FlowDiagram() {
|
||||
super(UmlDiagramType.FLOW);
|
||||
}
|
||||
|
||||
public void lineSimple(TileGeometry orientation, String idDest, String label) {
|
||||
|
@ -67,6 +67,7 @@ public class GitDiagram extends UmlDiagram {
|
||||
private final Collection<GNode> gnodes;
|
||||
|
||||
public GitDiagram(GitTextArea textArea) {
|
||||
super(UmlDiagramType.GIT);
|
||||
this.gnodes = new GNodeBuilder(textArea.getAllCommits()).getAllNodes();
|
||||
new GNodeBuilder(textArea.getAllCommits());
|
||||
}
|
||||
@ -75,10 +76,6 @@ public class GitDiagram extends UmlDiagram {
|
||||
return new DiagramDescription("(Git)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.GIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
|
||||
|
92
src/net/sourceforge/plantuml/graphic/StyledString.java
Normal file
92
src/net/sourceforge/plantuml/graphic/StyledString.java
Normal file
@ -0,0 +1,92 @@
|
||||
/* ========================================================================
|
||||
* 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.graphic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.StringUtils;
|
||||
|
||||
public class StyledString {
|
||||
|
||||
private final String text;
|
||||
private final FontStyle style;
|
||||
|
||||
private StyledString(String text, FontStyle style) {
|
||||
this.text = text;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return style + "[" + text + "]";
|
||||
}
|
||||
|
||||
public final String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public final FontStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public static List<StyledString> build(String s) {
|
||||
final List<StyledString> result = new ArrayList<StyledString>();
|
||||
while (s.length() > 0) {
|
||||
final int i1 = s.indexOf(StringUtils.BOLD_START);
|
||||
if (i1 == -1) {
|
||||
result.add(new StyledString(s, FontStyle.PLAIN));
|
||||
s = "";
|
||||
break;
|
||||
}
|
||||
final int i2 = s.indexOf(StringUtils.BOLD_END);
|
||||
if (i1 > 0)
|
||||
result.add(new StyledString(s.substring(0, i1), FontStyle.PLAIN));
|
||||
|
||||
if (i2 == -1) {
|
||||
result.add(new StyledString(s.substring(i1 + 1), FontStyle.BOLD));
|
||||
s = "";
|
||||
} else {
|
||||
result.add(new StyledString(s.substring(i1 + 1, i2), FontStyle.BOLD));
|
||||
s = s.substring(i2 + 1);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(result);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -66,9 +66,8 @@ public class Help extends UmlDiagram {
|
||||
return new DiagramDescription("(Help)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.HELP;
|
||||
public Help() {
|
||||
super(UmlDiagramType.HELP);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,7 +74,8 @@ public class JsonDiagram extends UmlDiagram {
|
||||
private final JsonValue root;
|
||||
private final List<String> highlighted;
|
||||
|
||||
public JsonDiagram(JsonValue json, List<String> highlighted) {
|
||||
public JsonDiagram(UmlDiagramType type, JsonValue json, List<String> highlighted) {
|
||||
super(UmlDiagramType.JSON);
|
||||
if (json != null && (json.isString() || json.isBoolean() || json.isNumber())) {
|
||||
this.root = new JsonArray();
|
||||
((JsonArray) this.root).add(json);
|
||||
@ -85,14 +86,12 @@ public class JsonDiagram extends UmlDiagram {
|
||||
}
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
if (getUmlDiagramType() == UmlDiagramType.YAML) {
|
||||
return new DiagramDescription("(Yaml)");
|
||||
}
|
||||
return new DiagramDescription("(Json)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.JSON;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
|
||||
throws IOException {
|
||||
@ -124,7 +123,8 @@ public class JsonDiagram extends UmlDiagram {
|
||||
|
||||
private void drawInternal(UGraphic ug) {
|
||||
if (root == null) {
|
||||
final Display display = Display.getWithNewlines("Your data does not sound like JSON data");
|
||||
final Display display = Display
|
||||
.getWithNewlines("Your data does not sound like " + getUmlDiagramType() + " data");
|
||||
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.courier(14));
|
||||
TextBlock result = display.create(fontConfiguration, HorizontalAlignment.LEFT, getSkinParam());
|
||||
result = TextBlockUtils.withMargin(result, 5, 2);
|
||||
|
@ -41,6 +41,7 @@ import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.BackSlash;
|
||||
import net.sourceforge.plantuml.StringLocated;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.command.PSystemAbstractFactory;
|
||||
import net.sourceforge.plantuml.core.Diagram;
|
||||
import net.sourceforge.plantuml.core.DiagramType;
|
||||
@ -81,7 +82,9 @@ public class JsonDiagramFactory extends PSystemAbstractFactory {
|
||||
} catch (ParseException e) {
|
||||
json = null;
|
||||
}
|
||||
return new JsonDiagram(json, highlighted);
|
||||
final JsonDiagram result = new JsonDiagram(UmlDiagramType.JSON, json, highlighted);
|
||||
result.setSource(source);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -80,16 +80,16 @@ public class SmetanaForJson {
|
||||
private ST_Agraph_s g;
|
||||
private StringBounder stringBounder;
|
||||
|
||||
private final List<Node> nodes = new ArrayList<Node>();
|
||||
private final List<InternalNode> nodes = new ArrayList<InternalNode>();
|
||||
private final List<ST_Agedge_s> edges = new ArrayList<ST_Agedge_s>();
|
||||
private Mirror xMirror;
|
||||
|
||||
static class Node {
|
||||
static class InternalNode {
|
||||
|
||||
private final TextBlockJson block;
|
||||
private final ST_Agnode_s node;
|
||||
|
||||
public Node(TextBlockJson block, ST_Agnode_s node) {
|
||||
public InternalNode(TextBlockJson block, ST_Agnode_s node) {
|
||||
this.block = block;
|
||||
this.node = node;
|
||||
}
|
||||
@ -118,7 +118,7 @@ public class SmetanaForJson {
|
||||
final TextBlockJson block = new TextBlockJson(skinParam, current, highlighted);
|
||||
final ST_Agnode_s node1 = createNode(block.calculateDimension(stringBounder), block.size(), current.isArray(),
|
||||
(int) block.getWidthColA(stringBounder), (int) block.getWidthColB(stringBounder));
|
||||
nodes.add(new Node(block, node1));
|
||||
nodes.add(new InternalNode(block, node1));
|
||||
final List<JsonValue> children = block.children();
|
||||
final List<String> keys = block.keys();
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
@ -151,12 +151,12 @@ public class SmetanaForJson {
|
||||
public void drawMe(JsonValue root, List<String> highlighted) {
|
||||
initGraph(root, highlighted);
|
||||
double max = 0;
|
||||
for (Node node : nodes) {
|
||||
for (InternalNode node : nodes) {
|
||||
max = Math.max(max, node.getMaxX());
|
||||
}
|
||||
xMirror = new Mirror(max);
|
||||
|
||||
for (Node node : nodes) {
|
||||
for (InternalNode node : nodes) {
|
||||
node.block.drawU(ug.apply(getPosition(node.node)));
|
||||
}
|
||||
final HColor color = getStyle().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());
|
||||
|
@ -42,8 +42,10 @@ 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.RegexResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
|
||||
public class CommandMindMapPlus extends SingleLineCommand2<MindMapDiagram> {
|
||||
|
||||
@ -54,6 +56,7 @@ public class CommandMindMapPlus extends SingleLineCommand2<MindMapDiagram> {
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandMindMapPlus.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("TYPE", "([+-]+)"), //
|
||||
new RegexOptional(new RegexLeaf("BACKCOLOR", "\\[(#\\w+)\\]")), //
|
||||
new RegexLeaf("SHAPE", "(_)?"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("LABEL", "([^%s].*)"), RegexLeaf.end());
|
||||
@ -63,8 +66,13 @@ public class CommandMindMapPlus extends SingleLineCommand2<MindMapDiagram> {
|
||||
protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) {
|
||||
final String type = arg.get("TYPE", 0);
|
||||
final String label = arg.get("LABEL", 0);
|
||||
final String stringColor = arg.get("BACKCOLOR", 0);
|
||||
HColor backColor = null;
|
||||
if (stringColor != null) {
|
||||
backColor = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(stringColor);
|
||||
}
|
||||
final Direction direction = type.contains("-") ? Direction.LEFT : Direction.RIGHT;
|
||||
return diagram.addIdea(null, type.length() - 1, Display.getWithNewlines(label),
|
||||
return diagram.addIdea(backColor, type.length() - 1, Display.getWithNewlines(label),
|
||||
IdeaShape.fromDesc(arg.get("SHAPE", 0)), direction);
|
||||
}
|
||||
|
||||
|
@ -87,9 +87,8 @@ public class MindMapDiagram extends UmlDiagram {
|
||||
return new DiagramDescription("MindMap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.MINDMAP;
|
||||
public MindMapDiagram() {
|
||||
super(UmlDiagramType.MINDMAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,9 +92,8 @@ public class NwDiagram extends UmlDiagram {
|
||||
return new DiagramDescription("(Nwdiag)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.NWDIAG;
|
||||
public NwDiagram() {
|
||||
super(UmlDiagramType.NWDIAG);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
@ -39,6 +39,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinSimple;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Code;
|
||||
@ -57,10 +58,10 @@ import net.sourceforge.plantuml.utils.UniqueSequence;
|
||||
|
||||
public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram {
|
||||
|
||||
public AbstractClassOrObjectDiagram(ISkinSimple orig) {
|
||||
super(orig);
|
||||
public AbstractClassOrObjectDiagram(UmlDiagramType type, ISkinSimple orig) {
|
||||
super(type, orig);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Ident cleanIdent(Ident ident) {
|
||||
String codeString = ident.getName();
|
||||
@ -70,18 +71,16 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
|
||||
return ident;
|
||||
}
|
||||
|
||||
|
||||
final public boolean insertBetween(IEntity entity1, IEntity entity2, IEntity node) {
|
||||
final Link link = foundLink(entity1, entity2);
|
||||
if (link == null) {
|
||||
return false;
|
||||
}
|
||||
final Link l1 = new Link(entity1, node, link.getType(), link.getLabel(), link.getLength(),
|
||||
link.getQualifier1(), null, link.getLabeldistance(), link.getLabelangle(), getSkinParam()
|
||||
.getCurrentStyleBuilder());
|
||||
final Link l1 = new Link(entity1, node, link.getType(), link.getLabel(), link.getLength(), link.getQualifier1(),
|
||||
null, link.getLabeldistance(), link.getLabelangle(), getSkinParam().getCurrentStyleBuilder());
|
||||
final Link l2 = new Link(node, entity2, link.getType(), link.getLabel(), link.getLength(), null,
|
||||
link.getQualifier2(), link.getLabeldistance(), link.getLabelangle(), getSkinParam()
|
||||
.getCurrentStyleBuilder());
|
||||
link.getQualifier2(), link.getLabeldistance(), link.getLabelangle(),
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
addLink(l1);
|
||||
addLink(l2);
|
||||
removeLink(link);
|
||||
@ -146,8 +145,8 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
|
||||
insertPointBetween(entity2A, entity2B, point2);
|
||||
|
||||
final int length = 1;
|
||||
final Link point1ToPoint2 = new Link(point1, point2, linkType, label, length, getSkinParam()
|
||||
.getCurrentStyleBuilder());
|
||||
final Link point1ToPoint2 = new Link(point1, point2, linkType, label, length,
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
addLink(point1ToPoint2);
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
@ -164,15 +163,15 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
|
||||
removeLink(existingLink1);
|
||||
}
|
||||
|
||||
final IEntity entity1real = existingLink1.isInverted() ? existingLink1.getEntity2() : existingLink1
|
||||
.getEntity1();
|
||||
final IEntity entity2real = existingLink1.isInverted() ? existingLink1.getEntity1() : existingLink1
|
||||
.getEntity2();
|
||||
final IEntity entity1real = existingLink1.isInverted() ? existingLink1.getEntity2()
|
||||
: existingLink1.getEntity1();
|
||||
final IEntity entity2real = existingLink1.isInverted() ? existingLink1.getEntity1()
|
||||
: existingLink1.getEntity2();
|
||||
|
||||
final Link entity1ToPoint = new Link(entity1real, point1, existingLink1.getType().getPart2(),
|
||||
existingLink1.getLabel(), existingLink1.getLength(), existingLink1.getQualifier1(), null,
|
||||
existingLink1.getLabeldistance(), existingLink1.getLabelangle(), getSkinParam()
|
||||
.getCurrentStyleBuilder());
|
||||
existingLink1.getLabeldistance(), existingLink1.getLabelangle(),
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
entity1ToPoint.setLinkArrow(existingLink1.getLinkArrow());
|
||||
final Link pointToEntity2 = new Link(point1, entity2real, existingLink1.getType().getPart1(), Display.NULL,
|
||||
existingLink1.getLength(), null, existingLink1.getQualifier2(), existingLink1.getLabeldistance(),
|
||||
@ -267,16 +266,16 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
|
||||
void createNew(int mode, LinkType linkType, Display label) {
|
||||
existingLink = foundLink(entity1, entity2);
|
||||
if (existingLink == null) {
|
||||
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL,
|
||||
2, getSkinParam().getCurrentStyleBuilder());
|
||||
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL, 2,
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
} else {
|
||||
removeLink(existingLink);
|
||||
}
|
||||
|
||||
final IEntity entity1real = existingLink.isInverted() ? existingLink.getEntity2() : existingLink
|
||||
.getEntity1();
|
||||
final IEntity entity2real = existingLink.isInverted() ? existingLink.getEntity1() : existingLink
|
||||
.getEntity2();
|
||||
final IEntity entity1real = existingLink.isInverted() ? existingLink.getEntity2()
|
||||
: existingLink.getEntity1();
|
||||
final IEntity entity2real = existingLink.isInverted() ? existingLink.getEntity1()
|
||||
: existingLink.getEntity2();
|
||||
|
||||
entity1ToPoint = new Link(entity1real, point, existingLink.getType().getPart2(), existingLink.getLabel(),
|
||||
existingLink.getLength(), existingLink.getQualifier1(), null, existingLink.getLabeldistance(),
|
||||
@ -303,11 +302,11 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
|
||||
addLink(pointToEntity2);
|
||||
|
||||
if (mode == 1) {
|
||||
pointToAssocied = new Link(point, associed, linkType, label, length, getSkinParam()
|
||||
.getCurrentStyleBuilder());
|
||||
pointToAssocied = new Link(point, associed, linkType, label, length,
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
} else {
|
||||
pointToAssocied = new Link(associed, point, linkType, label, length, getSkinParam()
|
||||
.getCurrentStyleBuilder());
|
||||
pointToAssocied = new Link(associed, point, linkType, label, length,
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
}
|
||||
addLink(pointToAssocied);
|
||||
}
|
||||
@ -315,8 +314,8 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram
|
||||
void createInSecond(LinkType linkType, Display label) {
|
||||
existingLink = foundLink(entity1, entity2);
|
||||
if (existingLink == null) {
|
||||
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL,
|
||||
2, getSkinParam().getCurrentStyleBuilder());
|
||||
existingLink = new Link(entity1, entity2, new LinkType(LinkDecor.NONE, LinkDecor.NONE), Display.NULL, 2,
|
||||
getSkinParam().getCurrentStyleBuilder());
|
||||
} else {
|
||||
removeLink(existingLink);
|
||||
}
|
||||
|
@ -65,9 +65,8 @@ public class PostItDiagram extends UmlDiagram {
|
||||
|
||||
private final Map<String, PostIt> postIts = new HashMap<String, PostIt>();
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return null;
|
||||
public PostItDiagram() {
|
||||
super(UmlDiagramType.TIMING);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,15 +130,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
private Day printStart;
|
||||
private Day printEnd;
|
||||
|
||||
private HColor linksColor = HColorUtils.RED_DARK;
|
||||
private HColor linksColor = null;
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
return new DiagramDescription("(Project)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.GANTT;
|
||||
public GanttDiagram() {
|
||||
super(UmlDiagramType.GANTT);
|
||||
}
|
||||
|
||||
private int horizontalPages = 1;
|
||||
@ -261,12 +260,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
if (openClose.getCalendar() == null) {
|
||||
return new TimeHeaderSimple(min, max);
|
||||
} else if (printScale == PrintScale.WEEKLY) {
|
||||
return new TimeHeaderWeekly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, nameDays);
|
||||
return new TimeHeaderWeekly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
|
||||
nameDays);
|
||||
} else if (printScale == PrintScale.MONTHLY) {
|
||||
return new TimeHeaderMonthly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, nameDays);
|
||||
return new TimeHeaderMonthly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
|
||||
nameDays);
|
||||
} else {
|
||||
return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, nameDays,
|
||||
printStart, printEnd);
|
||||
return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
|
||||
nameDays, printStart, printEnd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,19 +294,17 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
if (printStart != null && constraint.isHidden(min, max)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the linksColor is the default color, we should try to get the arrow color (default is RED_DARK)
|
||||
if (linksColor == HColorUtils.RED_DARK) {
|
||||
constraint.getUDrawable(timeScale, getLinkColor(), this).drawU(ug);
|
||||
} else {
|
||||
constraint.getUDrawable(timeScale, linksColor, this).drawU(ug);
|
||||
}
|
||||
constraint.getUDrawable(timeScale, getLinkColor(), this).drawU(ug);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private HColor getLinkColor() {
|
||||
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(getCurrentStyleBuilder());
|
||||
return styleArrow.value(PName.LineColor).asColor(colorSet);
|
||||
if (linksColor == null) {
|
||||
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(getCurrentStyleBuilder());
|
||||
return styleArrow.value(PName.LineColor).asColor(colorSet);
|
||||
}
|
||||
return linksColor;
|
||||
}
|
||||
|
||||
public StyleSignature getDefaultStyleDefinitionArrow() {
|
||||
@ -596,7 +595,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
return openClose.getLoadAt(day) > 0;
|
||||
}
|
||||
|
||||
public void affectResource(Task result, String description) {
|
||||
public boolean affectResource(Task result, String description) {
|
||||
final Pattern p = Pattern.compile("([^:]+)(:(\\d+))?");
|
||||
final Matcher m = p.matcher(description);
|
||||
if (m.find() == false) {
|
||||
@ -607,7 +606,11 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
if (m.group(3) != null) {
|
||||
percentage = Integer.parseInt(m.group(3));
|
||||
}
|
||||
if (percentage == 0) {
|
||||
return false;
|
||||
}
|
||||
result.addResource(resource, percentage);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Resource getResource(String resourceName) {
|
||||
@ -677,7 +680,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
public void colorDay(DayOfWeek day, HColor color) {
|
||||
colorDaysOfWeek.put(day, color);
|
||||
}
|
||||
|
||||
|
||||
public void nameDay(Day day, String name) {
|
||||
nameDays.put(day, name);
|
||||
}
|
||||
@ -734,4 +737,4 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -103,7 +103,7 @@ public class TimeHeaderDaily extends TimeHeader {
|
||||
final double x2 = getTimeScale().getEndingPosition(wink);
|
||||
HColor back = colorDays.get(wink);
|
||||
// Day of week should be stronger than period of time (back color).
|
||||
HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
|
||||
final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
|
||||
if (backDoW != null) {
|
||||
back = backDoW;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public class TimeHeaderWeekly extends TimeHeader {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
|
||||
HColor back = colorDays.get(wink);
|
||||
// Day of week should be stronger than period of time (back color).
|
||||
HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
|
||||
final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
|
||||
if (backDoW != null) {
|
||||
back = backDoW;
|
||||
}
|
||||
|
@ -63,7 +63,10 @@ public class SubjectTask implements Subject {
|
||||
for (final StringTokenizer st = new StringTokenizer(resource, "{}"); st.hasMoreTokens();) {
|
||||
final String part = st.nextToken().trim();
|
||||
if (part.length() > 0) {
|
||||
project.affectResource(result, part);
|
||||
final boolean ok = project.affectResource(result, part);
|
||||
if (ok == false) {
|
||||
return Failable.error("Bad argument for resource");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,14 @@ public class SolverImpl extends AbstractSolver implements Solver {
|
||||
protected Day computeEnd() {
|
||||
Day current = (Day) values.get(TaskAttribute.START);
|
||||
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
|
||||
int cpt = 0;
|
||||
while (fullLoad > 0) {
|
||||
fullLoad -= loadPlanable.getLoadAt(current);
|
||||
current = current.increment();
|
||||
cpt++;
|
||||
if (cpt > 100000) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
return current.decrement();
|
||||
}
|
||||
@ -63,12 +68,17 @@ public class SolverImpl extends AbstractSolver implements Solver {
|
||||
protected Day computeStart() {
|
||||
Day current = (Day) values.get(TaskAttribute.END);
|
||||
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
|
||||
int cpt = 0;
|
||||
while (fullLoad > 0) {
|
||||
fullLoad -= loadPlanable.getLoadAt(current);
|
||||
current = current.decrement();
|
||||
if (current.getMillis() <= 0) {
|
||||
return current;
|
||||
}
|
||||
cpt++;
|
||||
if (cpt > 100000) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
return current.increment();
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ public class PSystemSalt extends TitledDiagram implements WithSprite {
|
||||
|
||||
@Deprecated
|
||||
public PSystemSalt(List<String> data) {
|
||||
super(UmlDiagramType.SALT);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@ -280,11 +281,6 @@ public class PSystemSalt extends TitledDiagram implements WithSprite {
|
||||
this.iamSalt = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.SALT;
|
||||
}
|
||||
|
||||
public final boolean isIamSalt() {
|
||||
return iamSalt;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public class SequenceDiagram extends UmlDiagram {
|
||||
private final Rose skin2 = new Rose();
|
||||
|
||||
public SequenceDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.SEQUENCE, skinParam);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ -388,11 +388,6 @@ public class SequenceDiagram extends UmlDiagram {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.SEQUENCE;
|
||||
}
|
||||
|
||||
private ParticipantEnglober participantEnglober;
|
||||
|
||||
public void boxStart(Display comment, HColor color, Stereotype stereotype) {
|
||||
|
@ -112,7 +112,9 @@ public class CommandArrow extends SingleLineCommand2<SequenceDiagram> {
|
||||
new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), RegexLeaf.end());
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), //
|
||||
RegexLeaf.end());
|
||||
}
|
||||
|
||||
private Participant getOrCreateParticipant(SequenceDiagram system, RegexResult arg2, String n) {
|
||||
|
@ -35,7 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.skin;
|
||||
|
||||
|
||||
public enum ArrowDirection {
|
||||
LEFT_TO_RIGHT_NORMAL, RIGHT_TO_LEFT_REVERSE, SELF, BOTH_DIRECTION;
|
||||
|
||||
|
@ -68,18 +68,13 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
public class ListSpriteDiagram extends UmlDiagram {
|
||||
|
||||
public ListSpriteDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.HELP, skinParam);
|
||||
}
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
return new DiagramDescription("(Sprites)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
|
||||
throws IOException {
|
||||
|
@ -77,18 +77,13 @@ public class StdlibDiagram extends UmlDiagram {
|
||||
private String name;
|
||||
|
||||
public StdlibDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.HELP, skinParam);
|
||||
}
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
return new DiagramDescription("(Sprites)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
|
||||
throws IOException {
|
||||
|
@ -57,7 +57,7 @@ public class StateDiagram extends AbstractEntityDiagram {
|
||||
private static final String CONCURRENT_PREFIX = "CONC";
|
||||
|
||||
public StateDiagram(ISkinSimple skinParam) {
|
||||
super(skinParam);
|
||||
super(UmlDiagramType.STATE, skinParam);
|
||||
// setNamespaceSeparator(null);
|
||||
}
|
||||
|
||||
@ -260,11 +260,6 @@ public class StateDiagram extends AbstractEntityDiagram {
|
||||
super.endGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.STATE;
|
||||
}
|
||||
|
||||
private boolean hideEmptyDescription = false;
|
||||
|
||||
@Override
|
||||
|
@ -57,6 +57,7 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.png.PngIO;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.URectangle;
|
||||
@ -88,7 +89,7 @@ public class GraphicsSudoku {
|
||||
|
||||
public ImageData writeImageSvg(OutputStream os) throws IOException {
|
||||
final UGraphicSvg ug = new UGraphicSvg(true, new Dimension2DDouble(0, 0), new ColorMapperIdentity(),
|
||||
(String) null, false, 1.0, null, null, 0, "none", SvgCharSizeHack.NO_HACK);
|
||||
(String) null, false, 1.0, null, null, 0, "none", SvgCharSizeHack.NO_HACK, LengthAdjust.defaultValue());
|
||||
drawInternal(ug);
|
||||
ug.createXml(os, null);
|
||||
return ImageDataSimple.ok();
|
||||
|
@ -110,8 +110,9 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
|
||||
public static void checkOldVersionWarning(List<String> strings) {
|
||||
final long days = (System.currentTimeMillis() - Version.compileTime()) / 1000L / 3600 / 24;
|
||||
if (days >= 90) {
|
||||
strings.add("This version of PlantUML is " + days + " days old, so you should");
|
||||
strings.add(" consider upgrading from https://plantuml.com/download");
|
||||
strings.add(" ");
|
||||
strings.add("<b>This version of PlantUML is " + days + " days old, so you should");
|
||||
strings.add("<b>consider upgrading from https://plantuml.com/download");
|
||||
}
|
||||
}
|
||||
|
||||
|
44
src/net/sourceforge/plantuml/svg/LengthAdjust.java
Normal file
44
src/net/sourceforge/plantuml/svg/LengthAdjust.java
Normal file
@ -0,0 +1,44 @@
|
||||
/* ========================================================================
|
||||
* 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.svg;
|
||||
|
||||
public enum LengthAdjust {
|
||||
NONE, SPACING, SPACING_AND_GLYPHS;
|
||||
|
||||
public static LengthAdjust defaultValue() {
|
||||
return SPACING;
|
||||
}
|
||||
}
|
@ -118,6 +118,7 @@ public class SvgGraphics {
|
||||
private final String shadowId;
|
||||
private final String gradientId;
|
||||
private final boolean svgDimensionStyle;
|
||||
private final LengthAdjust lengthAdjust;
|
||||
|
||||
final protected void ensureVisible(double x, double y) {
|
||||
if (x > maxX) {
|
||||
@ -129,13 +130,14 @@ public class SvgGraphics {
|
||||
}
|
||||
|
||||
public SvgGraphics(boolean svgDimensionStyle, Dimension2D minDim, double scale, String hover, long seed,
|
||||
String preserveAspectRatio) {
|
||||
this(svgDimensionStyle, minDim, null, scale, hover, seed, preserveAspectRatio);
|
||||
String preserveAspectRatio, LengthAdjust lengthAdjust) {
|
||||
this(svgDimensionStyle, minDim, null, scale, hover, seed, preserveAspectRatio, lengthAdjust);
|
||||
}
|
||||
|
||||
public SvgGraphics(boolean svgDimensionStyle, Dimension2D minDim, String backcolor, double scale, String hover,
|
||||
long seed, String preserveAspectRatio) {
|
||||
long seed, String preserveAspectRatio, LengthAdjust lengthAdjust) {
|
||||
try {
|
||||
this.lengthAdjust = lengthAdjust;
|
||||
this.svgDimensionStyle = svgDimensionStyle;
|
||||
this.scale = scale;
|
||||
this.document = getDocument();
|
||||
@ -436,8 +438,15 @@ public class SvgGraphics {
|
||||
fillMe(elt);
|
||||
elt.setAttribute("font-size", format(fontSize));
|
||||
// elt.setAttribute("text-anchor", "middle");
|
||||
elt.setAttribute("lengthAdjust", "spacingAndGlyphs");
|
||||
elt.setAttribute("textLength", format(textLength));
|
||||
|
||||
if (lengthAdjust == LengthAdjust.SPACING) {
|
||||
elt.setAttribute("lengthAdjust", "spacing");
|
||||
elt.setAttribute("textLength", format(textLength));
|
||||
} else if (lengthAdjust == LengthAdjust.SPACING_AND_GLYPHS) {
|
||||
elt.setAttribute("lengthAdjust", "spacingAndGlyphs");
|
||||
elt.setAttribute("textLength", format(textLength));
|
||||
}
|
||||
|
||||
if (fontWeight != null) {
|
||||
elt.setAttribute("font-weight", fontWeight);
|
||||
}
|
||||
|
@ -218,6 +218,12 @@ public abstract class Eater {
|
||||
return s.charAt(i);
|
||||
}
|
||||
|
||||
final public boolean matchAffectation() {
|
||||
final String tmp = s.substring(i);
|
||||
final boolean result = tmp.matches("^\\$?[_\\p{L}][_\\p{L}0-9]*\\s*=.*");
|
||||
return result;
|
||||
}
|
||||
|
||||
final public char peekCharN2() {
|
||||
if (i + 1 >= s.length()) {
|
||||
return 0;
|
||||
|
@ -74,20 +74,34 @@ public class EaterFunctionCall extends Eater {
|
||||
final TValue result = TValue.fromString(value);
|
||||
values.add(result);
|
||||
} else if (unquoted) {
|
||||
final String read = eatAndGetOptionalQuotedString();
|
||||
if (TokenStack.isSpecialAffectationWhenFunctionCall(read)) {
|
||||
updateNamedArguments(read, context, memory);
|
||||
if (matchAffectation()) {
|
||||
final String varname = eatAndGetVarname();
|
||||
skipSpaces();
|
||||
checkAndEatChar('=');
|
||||
skipSpaces();
|
||||
final String read = eatAndGetOptionalQuotedString();
|
||||
final String value = context.applyFunctionsAndVariables(memory, getLineLocation(), read);
|
||||
final TValue result = TValue.fromString(value);
|
||||
namedArguments.put(varname, result);
|
||||
} else {
|
||||
final String read = eatAndGetOptionalQuotedString();
|
||||
final String value = context.applyFunctionsAndVariables(memory, getLineLocation(), read);
|
||||
final TValue result = TValue.fromString(value);
|
||||
values.add(result);
|
||||
}
|
||||
// }
|
||||
} else {
|
||||
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
|
||||
if (tokens.isSpecialAffectationWhenFunctionCall()) {
|
||||
final String special = tokens.tokenIterator().nextToken().getSurface();
|
||||
updateNamedArguments(special, context, memory);
|
||||
if (matchAffectation()) {
|
||||
final String varname = eatAndGetVarname();
|
||||
skipSpaces();
|
||||
checkAndEatChar('=');
|
||||
skipSpaces();
|
||||
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
|
||||
tokens.guessFunctions();
|
||||
final TValue result = tokens.getResult(getLineLocation(), context, memory);
|
||||
namedArguments.put(varname, result);
|
||||
} else {
|
||||
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
|
||||
tokens.guessFunctions();
|
||||
final TValue result = tokens.getResult(getLineLocation(), context, memory);
|
||||
values.add(result);
|
||||
@ -108,16 +122,6 @@ public class EaterFunctionCall extends Eater {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNamedArguments(String special, TContext context, TMemory memory)
|
||||
throws EaterException, EaterExceptionLocated {
|
||||
assert special.contains("=");
|
||||
final StringEater stringEater = new StringEater(special);
|
||||
final String varname = stringEater.eatAndGetVarname();
|
||||
stringEater.checkAndEatChar('=');
|
||||
final TValue expr = stringEater.eatExpression(context, memory);
|
||||
namedArguments.put(varname, expr);
|
||||
}
|
||||
|
||||
public final List<TValue> getValues() {
|
||||
return Collections.unmodifiableList(values);
|
||||
}
|
||||
|
@ -47,39 +47,38 @@ import net.sourceforge.plantuml.tim.Eater;
|
||||
import net.sourceforge.plantuml.tim.EaterException;
|
||||
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||
import net.sourceforge.plantuml.tim.TContext;
|
||||
import net.sourceforge.plantuml.tim.TLineType;
|
||||
import net.sourceforge.plantuml.tim.TMemory;
|
||||
|
||||
public class TokenStack {
|
||||
|
||||
final private List<Token> tokens;
|
||||
|
||||
public boolean isSpecialAffectationWhenFunctionCall() {
|
||||
if (tokens.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
final Token single = tokens.get(0);
|
||||
if (single.getTokenType() != TokenType.PLAIN_TEXT) {
|
||||
return false;
|
||||
}
|
||||
return isSpecialAffectationWhenFunctionCall(single.getSurface());
|
||||
}
|
||||
|
||||
public static boolean isSpecialAffectationWhenFunctionCall(String surface) {
|
||||
final int idx = surface.indexOf('=');
|
||||
if (idx <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (TLineType.isLetterOrUnderscoreOrDollar(surface.charAt(0)) == false) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i < idx; i++) {
|
||||
if (TLineType.isLetterOrUnderscoreOrDigit(surface.charAt(i)) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// public boolean isSpecialAffectationWhenFunctionCall() {
|
||||
// if (tokens.size() != 1) {
|
||||
// return false;
|
||||
// }
|
||||
// final Token single = tokens.get(0);
|
||||
// if (single.getTokenType() != TokenType.PLAIN_TEXT) {
|
||||
// return false;
|
||||
// }
|
||||
// return isSpecialAffectationWhenFunctionCall(single.getSurface());
|
||||
// }
|
||||
//
|
||||
// public static boolean isSpecialAffectationWhenFunctionCall(String surface) {
|
||||
// final int idx = surface.indexOf('=');
|
||||
// if (idx <= 0) {
|
||||
// return false;
|
||||
// }
|
||||
// if (TLineType.isLetterOrUnderscoreOrDollar(surface.charAt(0)) == false) {
|
||||
// return false;
|
||||
// }
|
||||
// for (int i = 1; i < idx; i++) {
|
||||
// if (TLineType.isLetterOrUnderscoreOrDigit(surface.charAt(i)) == false) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public TokenStack() {
|
||||
this(new ArrayList<Token>());
|
||||
|
@ -95,9 +95,8 @@ public class TimingDiagram extends UmlDiagram implements Clocks {
|
||||
return new DiagramDescription("(Timing Diagram)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.TIMING;
|
||||
public TimingDiagram() {
|
||||
super(UmlDiagramType.TIMING);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -60,6 +60,7 @@ import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.security.ImageIO;
|
||||
import net.sourceforge.plantuml.security.SFile;
|
||||
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.svg.SvgGraphics;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapperIdentity;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
@ -159,7 +160,8 @@ public class FontChecker {
|
||||
}
|
||||
|
||||
private String getSvgImage(char c) throws IOException, TransformerException {
|
||||
final SvgGraphics svg = new SvgGraphics(true, new Dimension2DDouble(0, 0), 1.0, null, 42, "none");
|
||||
final SvgGraphics svg = new SvgGraphics(true, new Dimension2DDouble(0, 0), 1.0, null, 42, "none",
|
||||
LengthAdjust.defaultValue());
|
||||
svg.setStrokeColor("black");
|
||||
svg.svgImage(getBufferedImage(c), 0, 0);
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
|
@ -71,6 +71,7 @@ import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.mjpeg.MJPEGGenerator;
|
||||
import net.sourceforge.plantuml.security.ImageIO;
|
||||
import net.sourceforge.plantuml.security.SFile;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorBackground;
|
||||
@ -283,7 +284,8 @@ public class ImageBuilder {
|
||||
option.getWatermark());
|
||||
case SVG:
|
||||
return createUGraphicSVG(colorMapper, param.getDpiFactor(), dim, param.getBackcolor(),
|
||||
option.getSvgLinkTarget(), option.getHoverColor(), seed, option.getPreserveAspectRatio());
|
||||
option.getSvgLinkTarget(), option.getHoverColor(), seed, option.getPreserveAspectRatio(),
|
||||
param.getlengthAdjust());
|
||||
case EPS:
|
||||
return new UGraphicEps(colorMapper, EpsStrategy.getDefault2());
|
||||
case EPS_TEXT:
|
||||
@ -307,7 +309,7 @@ public class ImageBuilder {
|
||||
}
|
||||
|
||||
private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scale, Dimension2D dim, final HColor suggested,
|
||||
String svgLinkTarget, String hover, long seed, String preserveAspectRatio) {
|
||||
String svgLinkTarget, String hover, long seed, String preserveAspectRatio, LengthAdjust lengthAdjust) {
|
||||
HColor backColor = HColorUtils.WHITE;
|
||||
if (suggested instanceof HColorSimple) {
|
||||
backColor = suggested;
|
||||
@ -316,14 +318,15 @@ public class ImageBuilder {
|
||||
final UGraphicSvg ug;
|
||||
if (suggested instanceof HColorGradient) {
|
||||
ug = new UGraphicSvg(dimensionStyle, dim, colorMapper, (HColorGradient) suggested, false, scale,
|
||||
svgLinkTarget, hover, seed, preserveAspectRatio, param.getSvgCharSizeHack());
|
||||
svgLinkTarget, hover, seed, preserveAspectRatio, param.getSvgCharSizeHack(),
|
||||
param.getlengthAdjust());
|
||||
} else if (backColor == null || colorMapper.toColor(backColor).equals(Color.WHITE)) {
|
||||
ug = new UGraphicSvg(dimensionStyle, dim, colorMapper, false, scale, svgLinkTarget, hover, seed,
|
||||
preserveAspectRatio, param.getSvgCharSizeHack());
|
||||
preserveAspectRatio, param.getSvgCharSizeHack(), param.getlengthAdjust());
|
||||
} else {
|
||||
final String tmp = colorMapper.toSvg(backColor);
|
||||
ug = new UGraphicSvg(dimensionStyle, dim, colorMapper, tmp, false, scale, svgLinkTarget, hover, seed,
|
||||
preserveAspectRatio, param.getSvgCharSizeHack());
|
||||
preserveAspectRatio, param.getSvgCharSizeHack(), param.getlengthAdjust());
|
||||
}
|
||||
return ug;
|
||||
|
||||
|
@ -43,6 +43,7 @@ import net.sourceforge.plantuml.SvgCharSizeHack;
|
||||
import net.sourceforge.plantuml.anim.Animation;
|
||||
import net.sourceforge.plantuml.skin.rose.Rose;
|
||||
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
|
||||
@ -58,6 +59,7 @@ public class ImageParameter {
|
||||
private final HColor backcolor;
|
||||
private final boolean svgDimensionStyle;
|
||||
private final SvgCharSizeHack svgCharSizeHack;
|
||||
private final LengthAdjust lengthAdjust;
|
||||
|
||||
private final UStroke borderStroke;
|
||||
private final HColor borderColor;
|
||||
@ -79,6 +81,7 @@ public class ImageParameter {
|
||||
this.borderCorner = 0;
|
||||
this.borderStroke = null;
|
||||
this.svgCharSizeHack = SvgCharSizeHack.NO_HACK;
|
||||
this.lengthAdjust = LengthAdjust.defaultValue();
|
||||
}
|
||||
|
||||
public ImageParameter(ISkinParam skinParam, Animation animation, double dpiFactor, String metadata,
|
||||
@ -104,6 +107,7 @@ public class ImageParameter {
|
||||
}
|
||||
|
||||
this.svgCharSizeHack = skinParam;
|
||||
this.lengthAdjust = skinParam.getlengthAdjust();
|
||||
|
||||
}
|
||||
|
||||
@ -159,4 +163,8 @@ public class ImageParameter {
|
||||
return svgCharSizeHack;
|
||||
}
|
||||
|
||||
public final LengthAdjust getlengthAdjust() {
|
||||
return lengthAdjust;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import net.sourceforge.plantuml.SvgCharSizeHack;
|
||||
import net.sourceforge.plantuml.eps.EpsStrategy;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.png.PngIO;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps;
|
||||
@ -66,7 +67,8 @@ public abstract class UGraphicUtils {
|
||||
final Dimension2D size = computeSize(colorMapper, background, image);
|
||||
final UGraphicSvg svg = new UGraphicSvg(true, size, colorMapper, colorMapper.toRGB(background), false, 1.0,
|
||||
fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor(), seed,
|
||||
fileFormatOption.getPreserveAspectRatio(), SvgCharSizeHack.NO_HACK);
|
||||
fileFormatOption.getPreserveAspectRatio(), SvgCharSizeHack.NO_HACK,
|
||||
LengthAdjust.defaultValue());
|
||||
image.drawU(svg);
|
||||
svg.createXml(os, fileFormatOption.isWithMetadata() ? metadata : null);
|
||||
} else if (fileFormat == FileFormat.EPS) {
|
||||
|
@ -44,16 +44,26 @@ public class UText implements UShape {
|
||||
|
||||
private final String text;
|
||||
private final FontConfiguration font;
|
||||
private final int orientation;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UText[" + text + "]";
|
||||
}
|
||||
|
||||
public UText(String text, FontConfiguration font) {
|
||||
private UText(String text, FontConfiguration font, int orientation) {
|
||||
assert text.indexOf('\t') == -1;
|
||||
this.text = text;
|
||||
this.font = font;
|
||||
this.orientation = orientation;
|
||||
}
|
||||
|
||||
public UText(String text, FontConfiguration font) {
|
||||
this(text, font, 0);
|
||||
}
|
||||
|
||||
public UText withOrientation(int orientation) {
|
||||
return new UText(text, font, orientation);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
@ -70,4 +80,8 @@ public class UText implements UShape {
|
||||
return descent;
|
||||
}
|
||||
|
||||
public final int getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,19 +40,20 @@ import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.EnsureVisible;
|
||||
import net.sourceforge.plantuml.FileFormat;
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.TikzFontDistortion;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.FontStyle;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.StyledString;
|
||||
import net.sourceforge.plantuml.ugraphic.UDriver;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UParam;
|
||||
@ -70,83 +71,108 @@ public class DriverTextG2d implements UDriver<Graphics2D> {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
private static void printFont() {
|
||||
final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
final String fontNames[] = ge.getAvailableFontFamilyNames();
|
||||
final int j = fontNames.length;
|
||||
for (int i = 0; i < j; i++) {
|
||||
Log.info("Available fonts: " + fontNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(UShape ushape, double x, double y, ColorMapper mapper, UParam param, Graphics2D g2d) {
|
||||
final UText shape = (UText) ushape;
|
||||
final FontConfiguration fontConfiguration = shape.getFontConfiguration();
|
||||
final String text = shape.getText();
|
||||
|
||||
final List<StyledString> strings = StyledString.build(text);
|
||||
|
||||
final UFont font = fontConfiguration.getFont().scaled(param.getScale());
|
||||
final Dimension2D dimBack = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
|
||||
|
||||
for (StyledString styledString : strings) {
|
||||
final FontConfiguration fc = styledString.getStyle() == FontStyle.BOLD ? fontConfiguration.bold()
|
||||
: fontConfiguration;
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), fc.getFont(),
|
||||
styledString.getText());
|
||||
printSingleText(g2d, fc, styledString.getText(), x, y, mapper, param);
|
||||
x += dim.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
private void printSingleText(Graphics2D g2d, final FontConfiguration fontConfiguration, final String text, double x,
|
||||
double y, ColorMapper mapper, UParam param) {
|
||||
final UFont font = fontConfiguration.getFont().scaled(param.getScale());
|
||||
final HColor extended = fontConfiguration.getExtendedColor();
|
||||
if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) {
|
||||
final Rectangle2D.Double area = new Rectangle2D.Double(x, y - dimBack.getHeight() + 1.5, dimBack.getWidth(),
|
||||
dimBack.getHeight());
|
||||
if (extended instanceof HColorGradient) {
|
||||
final GradientPaint paint = DriverRectangleG2d.getPaintGradient(x, y, mapper, dimBack.getWidth(),
|
||||
dimBack.getHeight(), extended);
|
||||
g2d.setPaint(paint);
|
||||
g2d.fill(area);
|
||||
} else {
|
||||
final Color backColor = mapper.toColor(extended);
|
||||
if (backColor != null) {
|
||||
g2d.setColor(backColor);
|
||||
g2d.setBackground(backColor);
|
||||
|
||||
final int orientation = 0;
|
||||
|
||||
if (orientation == 90) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g2d.setFont(font.getFont());
|
||||
g2d.setColor(mapper.toColor(fontConfiguration.getColor()));
|
||||
final AffineTransform orig = g2d.getTransform();
|
||||
g2d.translate(x, y);
|
||||
g2d.rotate(Math.PI / 2);
|
||||
g2d.drawString(text, 0, 0);
|
||||
g2d.setTransform(orig);
|
||||
|
||||
} else if (orientation == 0) {
|
||||
|
||||
final Dimension2D dimBack = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
|
||||
if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) {
|
||||
final Rectangle2D.Double area = new Rectangle2D.Double(x, y - dimBack.getHeight() + 1.5,
|
||||
dimBack.getWidth(), dimBack.getHeight());
|
||||
if (extended instanceof HColorGradient) {
|
||||
final GradientPaint paint = DriverRectangleG2d.getPaintGradient(x, y, mapper, dimBack.getWidth(),
|
||||
dimBack.getHeight(), extended);
|
||||
g2d.setPaint(paint);
|
||||
g2d.fill(area);
|
||||
} else {
|
||||
final Color backColor = mapper.toColor(extended);
|
||||
if (backColor != null) {
|
||||
g2d.setColor(backColor);
|
||||
g2d.setBackground(backColor);
|
||||
g2d.fill(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visible.ensureVisible(x, y - dimBack.getHeight() + 1.5);
|
||||
visible.ensureVisible(x + dimBack.getWidth(), y + 1.5);
|
||||
visible.ensureVisible(x, y - dimBack.getHeight() + 1.5);
|
||||
visible.ensureVisible(x + dimBack.getWidth(), y + 1.5);
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g2d.setFont(font.getFont());
|
||||
g2d.setColor(mapper.toColor(fontConfiguration.getColor()));
|
||||
g2d.drawString(shape.getText(), (float) x, (float) y);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g2d.setFont(font.getFont());
|
||||
g2d.setColor(mapper.toColor(fontConfiguration.getColor()));
|
||||
g2d.drawString(text, (float) x, (float) y);
|
||||
|
||||
if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) {
|
||||
if (extended != null) {
|
||||
g2d.setColor(mapper.toColor(extended));
|
||||
if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) {
|
||||
if (extended != null) {
|
||||
g2d.setColor(mapper.toColor(extended));
|
||||
}
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
|
||||
final int ypos = (int) (y + 2.5);
|
||||
g2d.setStroke(new BasicStroke((float) 1));
|
||||
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
|
||||
g2d.setStroke(new BasicStroke());
|
||||
}
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
|
||||
final int ypos = (int) (y + 2.5);
|
||||
g2d.setStroke(new BasicStroke((float) 1));
|
||||
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
|
||||
g2d.setStroke(new BasicStroke());
|
||||
}
|
||||
if (fontConfiguration.containsStyle(FontStyle.WAVE)) {
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
|
||||
final int ypos = (int) (y + 2.5) - 1;
|
||||
if (extended != null) {
|
||||
g2d.setColor(mapper.toColor(extended));
|
||||
if (fontConfiguration.containsStyle(FontStyle.WAVE)) {
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
|
||||
final int ypos = (int) (y + 2.5) - 1;
|
||||
if (extended != null) {
|
||||
g2d.setColor(mapper.toColor(extended));
|
||||
}
|
||||
for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) {
|
||||
g2d.drawLine(i, ypos - 0, i + 3, ypos + 1);
|
||||
g2d.drawLine(i + 3, ypos + 1, i + 6, ypos - 0);
|
||||
}
|
||||
}
|
||||
for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) {
|
||||
g2d.drawLine(i, ypos - 0, i + 3, ypos + 1);
|
||||
g2d.drawLine(i + 3, ypos + 1, i + 6, ypos - 0);
|
||||
if (fontConfiguration.containsStyle(FontStyle.STRIKE)) {
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, text);
|
||||
final FontMetrics fm = g2d.getFontMetrics(font.getFont());
|
||||
final int ypos = (int) (y - fm.getDescent() - 0.5);
|
||||
if (extended != null) {
|
||||
g2d.setColor(mapper.toColor(extended));
|
||||
}
|
||||
g2d.setStroke(new BasicStroke((float) 1.5));
|
||||
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
|
||||
g2d.setStroke(new BasicStroke());
|
||||
}
|
||||
}
|
||||
if (fontConfiguration.containsStyle(FontStyle.STRIKE)) {
|
||||
final Dimension2D dim = calculateDimension(
|
||||
FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()), font, shape.getText());
|
||||
final FontMetrics fm = g2d.getFontMetrics(font.getFont());
|
||||
final int ypos = (int) (y - fm.getDescent() - 0.5);
|
||||
if (extended != null) {
|
||||
g2d.setColor(mapper.toColor(extended));
|
||||
}
|
||||
g2d.setStroke(new BasicStroke((float) 1.5));
|
||||
g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos);
|
||||
g2d.setStroke(new BasicStroke());
|
||||
}
|
||||
}
|
||||
|
||||
static public Dimension2D calculateDimension(StringBounder stringBounder, UFont font, String text) {
|
||||
|
@ -47,6 +47,7 @@ import net.sourceforge.plantuml.Url;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.posimo.DotPath;
|
||||
import net.sourceforge.plantuml.svg.LengthAdjust;
|
||||
import net.sourceforge.plantuml.svg.SvgGraphics;
|
||||
import net.sourceforge.plantuml.ugraphic.AbstractCommonUGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.AbstractUGraphic;
|
||||
@ -90,23 +91,24 @@ public class UGraphicSvg extends AbstractUGraphic<SvgGraphics> implements ClipCo
|
||||
|
||||
public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, String backcolor,
|
||||
boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio,
|
||||
SvgCharSizeHack charSizeHack) {
|
||||
this(minDim, colorMapper,
|
||||
new SvgGraphics(svgDimensionStyle, minDim, backcolor, scale, hover, seed, preserveAspectRatio),
|
||||
textAsPath, linkTarget, charSizeHack);
|
||||
SvgCharSizeHack charSizeHack, LengthAdjust lengthAdjust) {
|
||||
this(minDim, colorMapper, new SvgGraphics(svgDimensionStyle, minDim, backcolor, scale, hover, seed,
|
||||
preserveAspectRatio, lengthAdjust), textAsPath, linkTarget, charSizeHack);
|
||||
}
|
||||
|
||||
public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, boolean textAsPath,
|
||||
double scale, String linkTarget, String hover, long seed, String preserveAspectRatio,
|
||||
SvgCharSizeHack charSizeHack) {
|
||||
this(minDim, colorMapper, new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio),
|
||||
SvgCharSizeHack charSizeHack, LengthAdjust lengthAdjust) {
|
||||
this(minDim, colorMapper,
|
||||
new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio, lengthAdjust),
|
||||
textAsPath, linkTarget, charSizeHack);
|
||||
}
|
||||
|
||||
public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper mapper, HColorGradient gr,
|
||||
boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio,
|
||||
SvgCharSizeHack charSizeHack) {
|
||||
this(minDim, mapper, new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio),
|
||||
SvgCharSizeHack charSizeHack, LengthAdjust lengthAdjust) {
|
||||
this(minDim, mapper,
|
||||
new SvgGraphics(svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio, lengthAdjust),
|
||||
textAsPath, linkTarget, charSizeHack);
|
||||
|
||||
final SvgGraphics svg = getGraphicObject();
|
||||
|
@ -44,7 +44,7 @@ public class Version {
|
||||
private static final int MAJOR_SEPARATOR = 1000000;
|
||||
|
||||
public static int version() {
|
||||
return 1202026;
|
||||
return 1202100;
|
||||
}
|
||||
|
||||
public static int versionPatched() {
|
||||
@ -93,7 +93,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static long compileTime() {
|
||||
return 1608572707669L;
|
||||
return 1610274305536L;
|
||||
}
|
||||
|
||||
public static String compileTimeString() {
|
||||
|
@ -75,9 +75,8 @@ public class WBSDiagram extends UmlDiagram {
|
||||
return new DiagramDescription("Work Breakdown Structure");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.WBS;
|
||||
public WBSDiagram() {
|
||||
super(UmlDiagramType.WBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,6 +43,8 @@ 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.RegexResult;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
|
||||
|
||||
public class CommandComponent extends SingleLineCommand2<WireDiagram> {
|
||||
|
||||
@ -53,7 +55,9 @@ public class CommandComponent extends SingleLineCommand2<WireDiagram> {
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandComponent.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("INDENT", "([\\s\\t]*)"), //
|
||||
new RegexLeaf("NAME", "\\$([\\w]+)"), //
|
||||
new RegexLeaf("\\*"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("NAME", "([\\w]+)"), //
|
||||
new RegexOptional(new RegexConcat( //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("\\["), //
|
||||
@ -62,6 +66,9 @@ public class CommandComponent extends SingleLineCommand2<WireDiagram> {
|
||||
new RegexLeaf("HEIGHT", "([\\d]+)"), //
|
||||
new RegexLeaf("\\]")) //
|
||||
), //
|
||||
new RegexOptional(new RegexConcat( //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("COLOR", "(#\\w+)?"))), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
RegexLeaf.end());
|
||||
}
|
||||
@ -80,7 +87,13 @@ public class CommandComponent extends SingleLineCommand2<WireDiagram> {
|
||||
height = Integer.parseInt(heightString);
|
||||
}
|
||||
|
||||
return diagram.addComponent(indent, name, width, height);
|
||||
final String stringColor = arg.get("COLOR", 0);
|
||||
HColor color = null;
|
||||
if (stringColor != null) {
|
||||
color = HColorSet.instance().getColorIfValid(stringColor);
|
||||
}
|
||||
|
||||
return diagram.addComponent(indent, name, width, height, color);
|
||||
}
|
||||
|
||||
}
|
||||
|
78
src/net/sourceforge/plantuml/wire/CommandPrint.java
Normal file
78
src/net/sourceforge/plantuml/wire/CommandPrint.java
Normal file
@ -0,0 +1,78 @@
|
||||
/* ========================================================================
|
||||
* 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.wire;
|
||||
|
||||
import net.sourceforge.plantuml.LineLocation;
|
||||
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;
|
||||
|
||||
public class CommandPrint extends SingleLineCommand2<WireDiagram> {
|
||||
|
||||
public CommandPrint() {
|
||||
super(false, getRegexConcat());
|
||||
}
|
||||
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandPrint.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("INDENT", "([\\s\\t]*)"), //
|
||||
new RegexLeaf("print"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("\\("), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("[%g]"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TEXT", "(.*)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("[%g]"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("\\)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
RegexLeaf.end());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) {
|
||||
final String indent = arg.get("INDENT", 0);
|
||||
final String text = arg.get("TEXT", 0);
|
||||
return diagram.print(indent, text);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -56,7 +56,7 @@ public class CommandSpot extends SingleLineCommand2<WireDiagram> {
|
||||
return RegexConcat.build(CommandSpot.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("spot"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("NAME", "\\$([\\w][.\\w]*)"), //
|
||||
new RegexLeaf("NAME", "([\\w][.\\w]*)"), //
|
||||
new RegexOptional(new RegexConcat(//
|
||||
new RegexLeaf("\\("), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
|
@ -43,6 +43,7 @@ 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.RegexResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
|
||||
|
||||
@ -54,7 +55,7 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
|
||||
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandWLink.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("NAME1", "\\$([\\w][.\\w]*)"), //
|
||||
new RegexLeaf("NAME1", "([\\w][.\\w]*)"), //
|
||||
new RegexOptional(new RegexConcat(//
|
||||
new RegexLeaf("\\("), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
@ -67,13 +68,15 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
|
||||
new RegexLeaf("\\)") //
|
||||
)), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STYLE", "([-=])\\>"), //
|
||||
new RegexLeaf("STYLE", "(\\<?[-=]{1,2}\\>|\\<?[-=]{1,2})"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("NAME2", "\\$([\\w][.\\w]*)"), //
|
||||
new RegexLeaf("NAME2", "([\\w][.\\w]*)"), //
|
||||
new RegexOptional(new RegexConcat( //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("COLOR", "(#\\w+)?"))), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
RegexLeaf.end());
|
||||
}
|
||||
|
||||
@ -83,9 +86,12 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
|
||||
final String name1 = arg.get("NAME1", 0);
|
||||
final String x1 = arg.get("X1", 0);
|
||||
final String y1 = arg.get("Y1", 0);
|
||||
|
||||
|
||||
final String name2 = arg.get("NAME2", 0);
|
||||
final WLinkType type = WLinkType.from(arg.get("STYLE", 0));
|
||||
final String style = arg.get("STYLE", 0);
|
||||
final WLinkType type = WLinkType.from(style);
|
||||
final WArrowDirection direction = WArrowDirection.from(style);
|
||||
final WOrientation orientation = WOrientation.from(style);
|
||||
|
||||
final String stringColor = arg.get("COLOR", 0);
|
||||
HColor color = null;
|
||||
@ -93,7 +99,18 @@ public class CommandWLink extends SingleLineCommand2<WireDiagram> {
|
||||
color = HColorSet.instance().getColorIfValid(stringColor);
|
||||
}
|
||||
|
||||
return diagram.link(name1, x1, y1, name2, type, color);
|
||||
final Display label;
|
||||
if (arg.get("MESSAGE", 0) == null) {
|
||||
label = Display.NULL;
|
||||
} else {
|
||||
final String message = arg.get("MESSAGE", 0);
|
||||
label = Display.getWithNewlines(message);
|
||||
}
|
||||
|
||||
if (orientation == WOrientation.VERTICAL) {
|
||||
return diagram.vlink(name1, x1, y1, name2, type, direction, color, label);
|
||||
}
|
||||
return diagram.hlink(name1, x1, y1, name2, type, direction, color, label);
|
||||
}
|
||||
|
||||
}
|
||||
|
54
src/net/sourceforge/plantuml/wire/WArrowDirection.java
Normal file
54
src/net/sourceforge/plantuml/wire/WArrowDirection.java
Normal file
@ -0,0 +1,54 @@
|
||||
/* ========================================================================
|
||||
* 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.wire;
|
||||
|
||||
public enum WArrowDirection {
|
||||
NORMAL, REVERSE, BOTH, NONE;
|
||||
|
||||
public static WArrowDirection from(String type) {
|
||||
if (type.contains("<") && type.contains(">")) {
|
||||
return BOTH;
|
||||
}
|
||||
if (type.contains(">")) {
|
||||
return NORMAL;
|
||||
}
|
||||
if (type.contains("<")) {
|
||||
return REVERSE;
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
}
|
@ -41,30 +41,41 @@ import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.SpriteContainerEmpty;
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.URectangle;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
|
||||
public class WBlock {
|
||||
|
||||
private final static int STARTING_Y = 10;
|
||||
|
||||
private final String name;
|
||||
private final double forcedWidth;
|
||||
private final double forcedHeight;
|
||||
private final HColor color;
|
||||
|
||||
private final List<WBlock> children = new ArrayList<WBlock>();
|
||||
private UTranslate position = new UTranslate();
|
||||
private final UTranslate position;
|
||||
private WBlock parent;
|
||||
|
||||
private UTranslate futureGoto;
|
||||
private UTranslate futureMove = new UTranslate(0, 20);
|
||||
private UTranslate cursor = new UTranslate(10, STARTING_Y);
|
||||
private WBlock addedToCursor = null;
|
||||
|
||||
private UTranslate futureOutHorizontal;
|
||||
private UTranslate futureOutVertical;
|
||||
|
||||
private final List<WPrint> prints = new ArrayList<WPrint>();
|
||||
|
||||
public UTranslate getAbsolutePosition(String supx, String supy) {
|
||||
if (parent == null) {
|
||||
@ -113,10 +124,12 @@ public class WBlock {
|
||||
return name + " " + position;
|
||||
}
|
||||
|
||||
public WBlock(String name, double width, double height) {
|
||||
public WBlock(String name, UTranslate position, double width, double height, HColor color) {
|
||||
this.name = name;
|
||||
this.forcedWidth = width;
|
||||
this.forcedHeight = height;
|
||||
this.color = color;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
private WBlock getChildByName(String name) {
|
||||
@ -147,8 +160,8 @@ public class WBlock {
|
||||
public CommandExecutionResult newColumn(int level) {
|
||||
if (level == 0) {
|
||||
final Dimension2D max = getNaturalDimension();
|
||||
futureGoto = new UTranslate(max.getWidth() + 10, 20);
|
||||
futureMove = new UTranslate();
|
||||
this.cursor = new UTranslate(max.getWidth() + 10, STARTING_Y);
|
||||
this.addedToCursor = null;
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
return getLastChild().newColumn(level - 1);
|
||||
@ -156,8 +169,8 @@ public class WBlock {
|
||||
|
||||
public CommandExecutionResult wgoto(int level, double x, double y) {
|
||||
if (level == 0) {
|
||||
futureGoto = new UTranslate(x, y);
|
||||
futureMove = new UTranslate();
|
||||
this.cursor = new UTranslate(x, y);
|
||||
this.addedToCursor = null;
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
return getLastChild().wgoto(level - 1, x, y);
|
||||
@ -165,13 +178,24 @@ public class WBlock {
|
||||
|
||||
public CommandExecutionResult wmove(int level, double x, double y) {
|
||||
if (level == 0) {
|
||||
futureMove = futureMove.compose(new UTranslate(x, y));
|
||||
this.cursor = this.cursor.compose(new UTranslate(x, y));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
return getLastChild().wmove(level - 1, x, y);
|
||||
}
|
||||
|
||||
public CommandExecutionResult addComponent(int level, String name, double width, double height) {
|
||||
public CommandExecutionResult print(StringBounder stringBounder, ISkinParam skinParam, int level, String text) {
|
||||
if (level == 0) {
|
||||
final WPrint print = new WPrint(skinParam, getNextPosition(), null, Display.getWithNewlines(text));
|
||||
this.prints.add(print);
|
||||
this.cursor = this.cursor.compose(UTranslate.dy(print.getHeight(stringBounder)));
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
return getLastChild().print(stringBounder, skinParam, level - 1, text);
|
||||
}
|
||||
|
||||
public CommandExecutionResult addBlock(int level, String name, double width, double height, HColor color) {
|
||||
if (name.contains(".")) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@ -179,8 +203,10 @@ public class WBlock {
|
||||
return CommandExecutionResult.error("Component exists already");
|
||||
}
|
||||
if (level == 0) {
|
||||
final WBlock newBlock = new WBlock(name, width, height);
|
||||
newBlock.position = getNextPosition();
|
||||
this.cursor = this.cursor.compose(UTranslate.dy(10));
|
||||
final WBlock newBlock = new WBlock(name, getNextPosition(), width, height, color);
|
||||
this.cursor = this.cursor.compose(UTranslate.dy(10));
|
||||
this.addedToCursor = newBlock;
|
||||
|
||||
children.add(newBlock);
|
||||
newBlock.parent = this;
|
||||
@ -188,25 +214,16 @@ public class WBlock {
|
||||
}
|
||||
|
||||
final WBlock last = getLastChild();
|
||||
return last.addComponent(level - 1, name, width, height);
|
||||
return last.addBlock(level - 1, name, width, height, color);
|
||||
}
|
||||
|
||||
private UTranslate getNextPosition() {
|
||||
final UTranslate result;
|
||||
if (futureGoto != null) {
|
||||
result = futureGoto.compose(futureMove);
|
||||
} else {
|
||||
final WBlock last = getLastChild();
|
||||
if (last == null) {
|
||||
result = futureMove.compose(UTranslate.dx(10));
|
||||
} else {
|
||||
final Dimension2D dim = last.getMaxDimension();
|
||||
result = last.position.compose(UTranslate.dy(dim.getHeight())).compose(futureMove);
|
||||
}
|
||||
if (this.addedToCursor != null) {
|
||||
final Dimension2D dim = this.addedToCursor.getMaxDimension();
|
||||
this.cursor = this.cursor.compose(UTranslate.dy(dim.getHeight()));
|
||||
}
|
||||
futureGoto = null;
|
||||
futureMove = new UTranslate(0, 20);
|
||||
return result;
|
||||
this.addedToCursor = null;
|
||||
return this.cursor;
|
||||
}
|
||||
|
||||
private WBlock getLastChild() {
|
||||
@ -230,11 +247,18 @@ public class WBlock {
|
||||
ug = ug.apply(HColorUtils.BLACK);
|
||||
if (name.length() > 0) {
|
||||
final URectangle rect = new URectangle(getMaxDimension());
|
||||
ug.draw(rect);
|
||||
UGraphic ugRect = ug;
|
||||
if (color != null) {
|
||||
ugRect = ugRect.apply(color.bg());
|
||||
}
|
||||
ugRect.draw(rect);
|
||||
}
|
||||
for (WBlock child : children) {
|
||||
child.drawMe(ug.apply(child.position));
|
||||
}
|
||||
for (WPrint print : prints) {
|
||||
print.drawMe(ug.apply(print.getPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
private Dimension2D getMaxDimension() {
|
||||
@ -260,20 +284,29 @@ public class WBlock {
|
||||
return new Dimension2DDouble(x, y);
|
||||
}
|
||||
|
||||
private UTranslate futureOut;
|
||||
|
||||
public UTranslate getNextOut(String x1, String y1, WLinkType type) {
|
||||
public UTranslate getNextOutHorizontal(String x, String y, WLinkType type) {
|
||||
final UTranslate result;
|
||||
if (x1 != null && y1 != null) {
|
||||
result = getAbsolutePosition(x1, y1);
|
||||
} else if (futureOut == null) {
|
||||
if (x != null && y != null) {
|
||||
result = getAbsolutePosition(x, y);
|
||||
} else if (futureOutHorizontal == null) {
|
||||
result = getAbsolutePosition("100%", "5");
|
||||
} else {
|
||||
result = futureOut;
|
||||
result = futureOutHorizontal;
|
||||
}
|
||||
futureOutHorizontal = result.compose(UTranslate.dy(type.spaceForNext()));
|
||||
return result;
|
||||
}
|
||||
|
||||
futureOut = result.compose(UTranslate.dy(type.ySpaceForNext()));
|
||||
|
||||
public UTranslate getNextOutVertical(String x, String y, WLinkType type) {
|
||||
final UTranslate result;
|
||||
if (x != null && y != null) {
|
||||
result = getAbsolutePosition(x, y);
|
||||
} else if (futureOutVertical == null) {
|
||||
result = getAbsolutePosition("5", "100%");
|
||||
} else {
|
||||
result = futureOutVertical;
|
||||
}
|
||||
futureOutVertical = result.compose(UTranslate.dx(type.spaceForNext()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
197
src/net/sourceforge/plantuml/wire/WLinkHorizontal.java
Normal file
197
src/net/sourceforge/plantuml/wire/WLinkHorizontal.java
Normal file
@ -0,0 +1,197 @@
|
||||
/* ========================================================================
|
||||
* 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.wire;
|
||||
|
||||
import java.awt.geom.Dimension2D;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.URectangle;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
|
||||
public class WLinkHorizontal {
|
||||
|
||||
private final UTranslate start;
|
||||
private final double destination;
|
||||
private final WLinkType type;
|
||||
private final WArrowDirection direction;
|
||||
private final HColor color;
|
||||
private final Display label;
|
||||
private final ISkinParam skinParam;
|
||||
|
||||
public WLinkHorizontal(ISkinParam skinParam, UTranslate start, double destination, WLinkType type,
|
||||
WArrowDirection direction, HColor color, Display label) {
|
||||
this.start = start;
|
||||
this.destination = destination;
|
||||
this.skinParam = skinParam;
|
||||
this.direction = direction;
|
||||
this.type = type;
|
||||
this.label = label;
|
||||
this.color = color == null ? HColorUtils.BLACK : color;
|
||||
}
|
||||
|
||||
private TextBlock getTextBlock() {
|
||||
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.sansSerif(10))
|
||||
.changeColor(color);
|
||||
return label.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
public void drawMe(UGraphic ug) {
|
||||
ug = ug.apply(color);
|
||||
final TextBlock textBlock = getTextBlock();
|
||||
final Dimension2D dimText = textBlock.calculateDimension(ug.getStringBounder());
|
||||
|
||||
UGraphic ugText = ug.apply(start);
|
||||
final double len = destination - start.getDx();
|
||||
|
||||
if (type == WLinkType.NORMAL) {
|
||||
ug = ug.apply(color.bg());
|
||||
drawNormalArrow(ug);
|
||||
|
||||
ugText = ugText.apply(UTranslate.dy(-dimText.getHeight() / 2));
|
||||
|
||||
} else if (type == WLinkType.BUS) {
|
||||
ug = ug.apply(HColorUtils.WHITE.bg());
|
||||
drawBusArrow(ug);
|
||||
ugText = ugText.apply(UTranslate.dy((20 - dimText.getHeight()) / 2 - 5));
|
||||
}
|
||||
|
||||
if (dimText.getHeight() > 0) {
|
||||
switch (direction) {
|
||||
case NORMAL:
|
||||
ugText = ugText.apply(UTranslate.dx(4));
|
||||
break;
|
||||
case REVERSE:
|
||||
ugText = ugText.apply(UTranslate.dx(len - dimText.getWidth() - 4));
|
||||
break;
|
||||
default:
|
||||
ugText = ugText.apply(UTranslate.dx((len - dimText.getWidth()) / 2));
|
||||
break;
|
||||
}
|
||||
if (type == WLinkType.NORMAL) {
|
||||
ugText.apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(new URectangle(dimText));
|
||||
}
|
||||
textBlock.drawU(ugText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawBusArrow(UGraphic ug) {
|
||||
final double dx = destination - start.getDx() - 2;
|
||||
final UPath path = new UPath();
|
||||
if (direction == WArrowDirection.NONE) {
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(dx, 0);
|
||||
path.lineTo(dx, 10);
|
||||
path.lineTo(0, 10);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.NORMAL) {
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(dx - 15, 0);
|
||||
path.lineTo(dx - 15, -5);
|
||||
path.lineTo(dx, 5);
|
||||
path.lineTo(dx - 15, 15);
|
||||
path.lineTo(dx - 15, 10);
|
||||
path.lineTo(0, 10);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.BOTH) {
|
||||
path.moveTo(0, 5);
|
||||
path.lineTo(15, -5);
|
||||
path.lineTo(15, 0);
|
||||
path.lineTo(dx - 15, 0);
|
||||
path.lineTo(dx - 15, -5);
|
||||
path.lineTo(dx, 5);
|
||||
path.lineTo(dx - 15, 15);
|
||||
path.lineTo(dx - 15, 10);
|
||||
path.lineTo(15, 10);
|
||||
path.lineTo(15, 15);
|
||||
path.lineTo(0, 5);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.REVERSE) {
|
||||
path.moveTo(0, 5);
|
||||
path.lineTo(15, -5);
|
||||
path.lineTo(15, 0);
|
||||
path.lineTo(dx, 0);
|
||||
path.lineTo(dx, 10);
|
||||
path.lineTo(15, 10);
|
||||
path.lineTo(15, 15);
|
||||
path.lineTo(0, 5);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawNormalArrow(UGraphic ug) {
|
||||
final double dx = destination - start.getDx() - 2;
|
||||
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.NORMAL) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(-5, -5);
|
||||
path.lineTo(-5, 5);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dx(dx))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.REVERSE) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(5, -5);
|
||||
path.lineTo(5, 5);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dx(1))).draw(path);
|
||||
}
|
||||
ug.apply(start.compose(UTranslate.dx(1))).draw(ULine.hline(dx));
|
||||
}
|
||||
|
||||
}
|
@ -40,16 +40,16 @@ public enum WLinkType {
|
||||
NORMAL, BUS;
|
||||
|
||||
static public WLinkType from(String arg) {
|
||||
if (arg.equals("-")) {
|
||||
if (arg.contains("-")) {
|
||||
return WLinkType.NORMAL;
|
||||
}
|
||||
if (arg.equals("=")) {
|
||||
if (arg.contains("=")) {
|
||||
return WLinkType.BUS;
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public double ySpaceForNext() {
|
||||
public double spaceForNext() {
|
||||
switch (this) {
|
||||
case NORMAL:
|
||||
return 15;
|
||||
|
164
src/net/sourceforge/plantuml/wire/WLinkVertical.java
Normal file
164
src/net/sourceforge/plantuml/wire/WLinkVertical.java
Normal file
@ -0,0 +1,164 @@
|
||||
/* ========================================================================
|
||||
* 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.wire;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
|
||||
public class WLinkVertical {
|
||||
|
||||
private final UTranslate start;
|
||||
private final double destination;
|
||||
private final WLinkType type;
|
||||
private final WArrowDirection direction;
|
||||
private final HColor color;
|
||||
private final Display label;
|
||||
private final ISkinParam skinParam;
|
||||
|
||||
public WLinkVertical(ISkinParam skinParam, UTranslate start, double destination, WLinkType type,
|
||||
WArrowDirection direction, HColor color, Display label) {
|
||||
this.start = start;
|
||||
this.destination = destination;
|
||||
this.skinParam = skinParam;
|
||||
this.direction = direction;
|
||||
this.type = type;
|
||||
this.label = label;
|
||||
this.color = color == null ? HColorUtils.BLACK : color;
|
||||
}
|
||||
|
||||
private TextBlock getTextBlock() {
|
||||
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.sansSerif(10))
|
||||
.changeColor(color);
|
||||
return label.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
public void drawMe(UGraphic ug) {
|
||||
ug = ug.apply(color);
|
||||
if (type == WLinkType.NORMAL) {
|
||||
ug = ug.apply(color.bg());
|
||||
drawNormalArrow(ug);
|
||||
} else if (type == WLinkType.BUS) {
|
||||
ug = ug.apply(HColorUtils.WHITE.bg());
|
||||
drawBusArrow(ug);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawBusArrow(UGraphic ug) {
|
||||
final double dy = destination - start.getDy() - 2;
|
||||
final UPath path = new UPath();
|
||||
if (direction == WArrowDirection.NONE) {
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(0, dy);
|
||||
path.lineTo(10, dy);
|
||||
path.lineTo(10, 0);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.NORMAL) {
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(0, dy - 15);
|
||||
path.lineTo(-5, dy - 15);
|
||||
path.lineTo(5, dy);
|
||||
path.lineTo(15, dy - 15);
|
||||
path.lineTo(10, dy - 15);
|
||||
path.lineTo(10, 0);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.BOTH) {
|
||||
path.moveTo(5, 0);
|
||||
path.lineTo(-5, 15);
|
||||
path.lineTo(0, 15);
|
||||
path.lineTo(0, dy - 15);
|
||||
path.lineTo(-5, dy - 15);
|
||||
path.lineTo(5, dy);
|
||||
path.lineTo(15, dy - 15);
|
||||
path.lineTo(10, dy - 15);
|
||||
path.lineTo(10, 15);
|
||||
path.lineTo(15, 15);
|
||||
path.lineTo(5, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.REVERSE) {
|
||||
path.moveTo(5, 0);
|
||||
path.lineTo(-5, 15);
|
||||
path.lineTo(0, 15);
|
||||
path.lineTo(0, dy);
|
||||
path.lineTo(10, dy);
|
||||
path.lineTo(10, 15);
|
||||
path.lineTo(15, 15);
|
||||
path.lineTo(5, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
|
||||
} }
|
||||
|
||||
private void drawNormalArrow(UGraphic ug) {
|
||||
final double dy = destination - start.getDy() - 2;
|
||||
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.NORMAL) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(5, -5);
|
||||
path.lineTo(-5, -5);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dy(dy))).draw(path);
|
||||
}
|
||||
if (direction == WArrowDirection.BOTH || direction == WArrowDirection.REVERSE) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(5, 5);
|
||||
path.lineTo(-5, 5);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(start.compose(UTranslate.dy(1))).draw(path);
|
||||
}
|
||||
ug.apply(start.compose(UTranslate.dy(1))).draw(ULine.vline(dy));
|
||||
}
|
||||
|
||||
}
|
48
src/net/sourceforge/plantuml/wire/WOrientation.java
Normal file
48
src/net/sourceforge/plantuml/wire/WOrientation.java
Normal file
@ -0,0 +1,48 @@
|
||||
/* ========================================================================
|
||||
* 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.wire;
|
||||
|
||||
public enum WOrientation {
|
||||
|
||||
HORIZONTAL, VERTICAL;
|
||||
|
||||
public static WOrientation from(String style) {
|
||||
if (style.contains("==") || style.contains("--")) {
|
||||
return WOrientation.VERTICAL;
|
||||
}
|
||||
return HORIZONTAL;
|
||||
}
|
||||
}
|
@ -35,57 +35,49 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.wire;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UChange;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
||||
|
||||
public class WLink {
|
||||
public class WPrint {
|
||||
|
||||
private final UTranslate pos1;
|
||||
private final double pos2x;
|
||||
private final WLinkType type;
|
||||
private final UTranslate position;
|
||||
private final HColor color;
|
||||
private final Display label;
|
||||
private final ISkinParam skinParam;
|
||||
|
||||
public WLink(WBlock block1, String x1, String y1, WBlock block2, WLinkType type, HColor color) {
|
||||
pos1 = block1.getNextOut(x1, y1, type);
|
||||
pos2x = block2.getAbsolutePosition("0", "0").getDx();
|
||||
this.type = type;
|
||||
public WPrint(ISkinParam skinParam, UTranslate position, HColor color, Display label) {
|
||||
this.position = position;
|
||||
this.skinParam = skinParam;
|
||||
this.label = label;
|
||||
this.color = color == null ? HColorUtils.BLACK : color;
|
||||
}
|
||||
|
||||
private TextBlock getTextBlock() {
|
||||
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.sansSerif(10))
|
||||
.changeColor(color);
|
||||
return label.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
public UChange getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void drawMe(UGraphic ug) {
|
||||
getTextBlock().drawU(ug);
|
||||
}
|
||||
|
||||
final double dx = pos2x - pos1.getDx() - 2;
|
||||
|
||||
ug = ug.apply(color).apply(color.bg());
|
||||
|
||||
if (type == WLinkType.NORMAL) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(-5, -5);
|
||||
path.lineTo(-5, 5);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(pos1.compose(UTranslate.dx(dx))).draw(path);
|
||||
ug.apply(pos1.compose(UTranslate.dx(1))).draw(ULine.hline(dx));
|
||||
|
||||
} else if (type == WLinkType.BUS) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(dx - 15, 0);
|
||||
path.lineTo(dx - 15, -5);
|
||||
path.lineTo(dx, 5);
|
||||
path.lineTo(dx - 15, 15);
|
||||
path.lineTo(dx - 15, 10);
|
||||
path.lineTo(0, 10);
|
||||
path.lineTo(0, 0);
|
||||
path.closePath();
|
||||
ug.apply(pos1.compose(UTranslate.dx(1))).draw(path);
|
||||
}
|
||||
|
||||
public double getHeight(StringBounder stringBounder) {
|
||||
return getTextBlock().calculateDimension(stringBounder).getHeight();
|
||||
}
|
||||
|
||||
}
|
@ -43,16 +43,19 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.AnnotatedWorker;
|
||||
import net.sourceforge.plantuml.FileFormat;
|
||||
import net.sourceforge.plantuml.FileFormatOption;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.Scale;
|
||||
import net.sourceforge.plantuml.SkinParam;
|
||||
import net.sourceforge.plantuml.TikzFontDistortion;
|
||||
import net.sourceforge.plantuml.UmlDiagram;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.UseStyle;
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.core.DiagramDescription;
|
||||
import net.sourceforge.plantuml.core.ImageData;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.graphic.InnerStrategy;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
@ -62,21 +65,22 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder;
|
||||
import net.sourceforge.plantuml.ugraphic.ImageParameter;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
|
||||
public class WireDiagram extends UmlDiagram {
|
||||
|
||||
private final WBlock root = new WBlock("", 0, 0);
|
||||
private final WBlock root = new WBlock("", new UTranslate(), 0, 0, null);
|
||||
private final List<Spot> spots = new ArrayList<Spot>();
|
||||
private final List<WLink> links = new ArrayList<WLink>();
|
||||
private final List<WLinkHorizontal> hlinks = new ArrayList<WLinkHorizontal>();
|
||||
private final List<WLinkVertical> vlinks = new ArrayList<WLinkVertical>();
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
return new DiagramDescription("Wire Diagram");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return UmlDiagramType.WIRE;
|
||||
public WireDiagram() {
|
||||
super(UmlDiagramType.WIRE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -145,19 +149,22 @@ public class WireDiagram extends UmlDiagram {
|
||||
for (Spot spot : spots) {
|
||||
spot.drawMe(ug);
|
||||
}
|
||||
for (WLink link : links) {
|
||||
for (WLinkHorizontal link : hlinks) {
|
||||
link.drawMe(ug);
|
||||
}
|
||||
for (WLinkVertical link : vlinks) {
|
||||
link.drawMe(ug);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CommandExecutionResult addComponent(String indent, String name, int width, int height) {
|
||||
final int level = indent.replace(" ", "\t").length();
|
||||
return this.root.addComponent(level, name, width, height);
|
||||
public CommandExecutionResult addComponent(String indent, String name, int width, int height, HColor color) {
|
||||
final int level = computeIndentationLevel(indent);
|
||||
return this.root.addBlock(level, name, width, height, color);
|
||||
}
|
||||
|
||||
public CommandExecutionResult newColumn(String indent) {
|
||||
final int level = indent.replace(" ", "\t").length();
|
||||
final int level = computeIndentationLevel(indent);
|
||||
return this.root.newColumn(level);
|
||||
}
|
||||
|
||||
@ -172,16 +179,29 @@ public class WireDiagram extends UmlDiagram {
|
||||
}
|
||||
|
||||
public CommandExecutionResult wgoto(String indent, double x, double y) {
|
||||
final int level = indent.replace(" ", "\t").length();
|
||||
final int level = computeIndentationLevel(indent);
|
||||
return this.root.wgoto(level, x, y);
|
||||
}
|
||||
|
||||
public CommandExecutionResult wmove(String indent, double x, double y) {
|
||||
final int level = indent.replace(" ", "\t").length();
|
||||
final int level = computeIndentationLevel(indent);
|
||||
return this.root.wmove(level, x, y);
|
||||
}
|
||||
|
||||
public CommandExecutionResult link(String name1, String x1, String y1, String name2, WLinkType type, HColor color) {
|
||||
public CommandExecutionResult print(String indent, String text) {
|
||||
final int level = computeIndentationLevel(indent);
|
||||
|
||||
final StringBounder stringBounder = FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault());
|
||||
return this.root.print(stringBounder, getSkinParam(), level, text);
|
||||
}
|
||||
|
||||
private int computeIndentationLevel(String indent) {
|
||||
final int level = indent.replace(" ", "\t").length();
|
||||
return level;
|
||||
}
|
||||
|
||||
public CommandExecutionResult vlink(String name1, String x1, String y1, String name2, WLinkType type,
|
||||
WArrowDirection direction, HColor color, Display label) {
|
||||
final WBlock block1 = this.root.getBlock(name1);
|
||||
if (block1 == null) {
|
||||
return CommandExecutionResult.error("No such element " + name1);
|
||||
@ -190,8 +210,30 @@ public class WireDiagram extends UmlDiagram {
|
||||
if (block2 == null) {
|
||||
return CommandExecutionResult.error("No such element " + name2);
|
||||
}
|
||||
final WLink link = new WLink(block1, x1, y1, block2, type, color);
|
||||
this.links.add(link);
|
||||
|
||||
final UTranslate start = block1.getNextOutVertical(x1, y1, type);
|
||||
final double destination = block2.getAbsolutePosition("0", "0").getDy();
|
||||
|
||||
this.vlinks.add(new WLinkVertical(getSkinParam(), start, destination, type, direction, color, label));
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
public CommandExecutionResult hlink(String name1, String x1, String y1, String name2, WLinkType type,
|
||||
WArrowDirection direction, HColor color, Display label) {
|
||||
final WBlock block1 = this.root.getBlock(name1);
|
||||
if (block1 == null) {
|
||||
return CommandExecutionResult.error("No such element " + name1);
|
||||
}
|
||||
final WBlock block2 = this.root.getBlock(name2);
|
||||
if (block2 == null) {
|
||||
return CommandExecutionResult.error("No such element " + name2);
|
||||
}
|
||||
|
||||
final UTranslate start = block1.getNextOutHorizontal(x1, y1, type);
|
||||
final double destination = block2.getAbsolutePosition("0", "0").getDx();
|
||||
|
||||
this.hlinks.add(new WLinkHorizontal(getSkinParam(), start, destination, type, direction, color, label));
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ public class WireDiagramFactory extends PSystemCommandFactory {
|
||||
cmds.add(new CommandMove());
|
||||
cmds.add(new CommandWLink());
|
||||
cmds.add(new CommandNewColumn());
|
||||
cmds.add(new CommandPrint());
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
273
src/net/sourceforge/plantuml/yaml/SimpleYamlParser.java
Normal file
273
src/net/sourceforge/plantuml/yaml/SimpleYamlParser.java
Normal file
@ -0,0 +1,273 @@
|
||||
/* ========================================================================
|
||||
* 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.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.json.JsonArray;
|
||||
import net.sourceforge.plantuml.json.JsonObject;
|
||||
import net.sourceforge.plantuml.json.JsonValue;
|
||||
|
||||
public class SimpleYamlParser {
|
||||
|
||||
private static final String KEY = "([_0-9\\w][- _0-9\\w]*)";
|
||||
|
||||
private JsonObject result;
|
||||
private final List<Integer> pendingIndents = new ArrayList<Integer>();
|
||||
|
||||
public JsonObject parse(List<String> lines) {
|
||||
List<String> tmp = new ArrayList<String>();
|
||||
for (String s : lines) {
|
||||
if (s.trim().length() == 0)
|
||||
continue;
|
||||
if (s.trim().startsWith("#"))
|
||||
continue;
|
||||
tmp.add(s);
|
||||
}
|
||||
tmp = mergeMultiline(tmp);
|
||||
result = new JsonObject();
|
||||
pendingIndents.clear();
|
||||
pendingIndents.add(0);
|
||||
for (String s : tmp) {
|
||||
parseSingleLine(s);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private List<String> mergeMultiline(List<String> tmp) {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
for (int i = 0; i < tmp.size(); i++) {
|
||||
if (nameOnly(tmp.get(i)) != null && textOnly(tmp.get(i + 1))) {
|
||||
final StringBuilder sb = new StringBuilder(tmp.get(i));
|
||||
while (textOnly(tmp.get(i + 1))) {
|
||||
sb.append(" " + tmp.get(i + 1).trim());
|
||||
i++;
|
||||
}
|
||||
result.add(sb.toString());
|
||||
} else {
|
||||
result.add(tmp.get(i));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String[] dashNameAndValue(String s) {
|
||||
final Pattern p1 = Pattern.compile("^\\s*[-]\\s*" + KEY + "\\s*:\\s*(\\S.*)$");
|
||||
final Matcher m1 = p1.matcher(s);
|
||||
if (m1.matches()) {
|
||||
final String name = m1.group(1);
|
||||
final String data = m1.group(2).trim();
|
||||
return new String[] { name, data };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] nameAndValue(String s) {
|
||||
final Pattern p1 = Pattern.compile("^\\s*" + KEY + "\\s*:\\s*(\\S.*)$");
|
||||
final Matcher m1 = p1.matcher(s);
|
||||
if (m1.matches()) {
|
||||
final String name = m1.group(1);
|
||||
final String data = m1.group(2).trim();
|
||||
return new String[] { name, data };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String nameOnly(String s) {
|
||||
final Pattern p1 = Pattern.compile("^\\s*" + KEY + "\\s*:\\s*\\|?\\s*$");
|
||||
final Matcher m1 = p1.matcher(s);
|
||||
if (m1.matches()) {
|
||||
final String name = m1.group(1);
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String listedValue(String s) {
|
||||
final Pattern p1 = Pattern.compile("^\\s*[-]\\s*(\\S.*)$");
|
||||
final Matcher m1 = p1.matcher(s);
|
||||
if (m1.matches()) {
|
||||
final String name = m1.group(1).trim();
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean textOnly(String s) {
|
||||
if (isList(s))
|
||||
return false;
|
||||
return s.indexOf(':') == -1;
|
||||
}
|
||||
|
||||
private void parseSingleLine(String s) {
|
||||
// System.err.println("s=" + s);
|
||||
final int indent = getIndent(s);
|
||||
|
||||
if (isListStrict(s)) {
|
||||
muteToArray(indent);
|
||||
return;
|
||||
}
|
||||
|
||||
final String[] dashNameAndValue = dashNameAndValue(s);
|
||||
if (dashNameAndValue != null) {
|
||||
muteToArray(indent);
|
||||
parseSingleLine(s.replaceFirst("[-]", " "));
|
||||
return;
|
||||
}
|
||||
|
||||
final String listedValue = listedValue(s);
|
||||
if (listedValue != null) {
|
||||
final JsonArray array = getForceArray(indent);
|
||||
array.add(listedValue);
|
||||
return;
|
||||
}
|
||||
|
||||
final JsonObject working = getWorking(indent);
|
||||
if (working == null) {
|
||||
System.err.println("ERROR: ignoring " + s);
|
||||
return;
|
||||
}
|
||||
|
||||
final String[] nameAndValue = nameAndValue(s);
|
||||
if (nameAndValue != null) {
|
||||
final String name = nameAndValue[0];
|
||||
final String data = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(nameAndValue[1], "\"");
|
||||
working.add(name, data);
|
||||
return;
|
||||
}
|
||||
|
||||
final String nameOnly = nameOnly(s);
|
||||
if (nameOnly != null) {
|
||||
working.add(nameOnly, new JsonObject());
|
||||
return;
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException(s);
|
||||
}
|
||||
|
||||
private JsonArray getForceArray(int indent) {
|
||||
while (getLastIndent() > indent - 1)
|
||||
pendingIndents.remove(pendingIndents.size() - 1);
|
||||
|
||||
final JsonObject last = search(result, pendingIndents.size());
|
||||
final String field = last.names().get(last.size() - 1);
|
||||
if (last.get(field) instanceof JsonArray == false) {
|
||||
last.set(field, new JsonArray());
|
||||
}
|
||||
return (JsonArray) last.get(field);
|
||||
}
|
||||
|
||||
private void muteToArray(int indent) {
|
||||
while (getLastIndent() > indent)
|
||||
pendingIndents.remove(pendingIndents.size() - 1);
|
||||
|
||||
final JsonObject last = search(result, pendingIndents.size());
|
||||
final String field = last.names().get(last.size() - 1);
|
||||
if (last.get(field) instanceof JsonArray == false) {
|
||||
last.set(field, new JsonArray());
|
||||
} else {
|
||||
((JsonArray) last.get(field)).add(new JsonObject());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isList(String s) {
|
||||
return s.trim().startsWith("-");
|
||||
}
|
||||
|
||||
private boolean isListStrict(String s) {
|
||||
return s.trim().equals("-");
|
||||
}
|
||||
|
||||
private int getLastIndent() {
|
||||
return pendingIndents.get(pendingIndents.size() - 1);
|
||||
}
|
||||
|
||||
private JsonObject getWorking(int indent) {
|
||||
if (indent > getLastIndent()) {
|
||||
pendingIndents.add(indent);
|
||||
return search(result, pendingIndents.size());
|
||||
}
|
||||
if (indent == getLastIndent()) {
|
||||
return search(result, pendingIndents.size());
|
||||
}
|
||||
final int idx = pendingIndents.indexOf(indent);
|
||||
if (idx == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (pendingIndents.size() > idx + 1)
|
||||
pendingIndents.remove(pendingIndents.size() - 1);
|
||||
|
||||
return search(result, pendingIndents.size());
|
||||
}
|
||||
|
||||
private static JsonObject search(JsonObject current, int size) {
|
||||
if (size <= 1) {
|
||||
return current;
|
||||
}
|
||||
final String last = current.names().get(current.size() - 1);
|
||||
// System.err.println("last=" + last);
|
||||
JsonValue tmp = current.get(last);
|
||||
if (tmp instanceof JsonArray) {
|
||||
JsonArray array = (JsonArray) tmp;
|
||||
if (array.size() == 0) {
|
||||
tmp = new JsonObject();
|
||||
array.add(tmp);
|
||||
} else {
|
||||
tmp = array.get(array.size() - 1);
|
||||
}
|
||||
}
|
||||
return search((JsonObject) tmp, size - 1);
|
||||
}
|
||||
|
||||
private int getIndent(String s) {
|
||||
int indent = 0;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
final char ch = s.charAt(i);
|
||||
if (ch == ' ' || ch == '\t') {
|
||||
indent++;
|
||||
} else {
|
||||
return indent;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
79
src/net/sourceforge/plantuml/yaml/YamlDiagramFactory.java
Normal file
79
src/net/sourceforge/plantuml/yaml/YamlDiagramFactory.java
Normal file
@ -0,0 +1,79 @@
|
||||
/* ========================================================================
|
||||
* 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.yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.StringLocated;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.command.PSystemAbstractFactory;
|
||||
import net.sourceforge.plantuml.core.Diagram;
|
||||
import net.sourceforge.plantuml.core.DiagramType;
|
||||
import net.sourceforge.plantuml.core.UmlSource;
|
||||
import net.sourceforge.plantuml.json.JsonObject;
|
||||
import net.sourceforge.plantuml.jsondiagram.JsonDiagram;
|
||||
|
||||
public class YamlDiagramFactory extends PSystemAbstractFactory {
|
||||
|
||||
public YamlDiagramFactory() {
|
||||
super(DiagramType.YAML);
|
||||
}
|
||||
|
||||
public Diagram createSystem(UmlSource source) {
|
||||
JsonObject yaml = null;
|
||||
try {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
final Iterator<StringLocated> it = source.iterator2();
|
||||
it.next();
|
||||
while (true) {
|
||||
final String line = it.next().getString();
|
||||
if (it.hasNext() == false) {
|
||||
break;
|
||||
}
|
||||
list.add(line);
|
||||
}
|
||||
yaml = new SimpleYamlParser().parse(list);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
final JsonDiagram result = new JsonDiagram(UmlDiagramType.YAML, yaml, new ArrayList<String>());
|
||||
result.setSource(source);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user