diff --git a/pom.xml b/pom.xml index 32e6716b3..85aeca85b 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ net.sourceforge.plantuml plantuml - 1.2019.6-SNAPSHOT + 1.2019.7-SNAPSHOT jar PlantUML diff --git a/src/net/sourceforge/plantuml/AnnotatedWorker.java b/src/net/sourceforge/plantuml/AnnotatedWorker.java index d0ae850d8..1afec513c 100644 --- a/src/net/sourceforge/plantuml/AnnotatedWorker.java +++ b/src/net/sourceforge/plantuml/AnnotatedWorker.java @@ -99,7 +99,7 @@ public class AnnotatedWorker { final double width = x1 + Math.max(dimOriginal.getWidth(), dimTitle.getWidth()) + x2; final double height = dimTitle.getHeight() + y1 + dimOriginal.getHeight() + y2; final TextBlock result = USymbol.FRAME.asBig(title, HorizontalAlignment.LEFT, TextBlockUtils.empty(0, 0), - width, height, symbolContext); + width, height, symbolContext, skinParam.getStereotypeAlignment()); return new TextBlockBackcolored() { diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index 1a827c5ea..73102e17b 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.code.Transcoder; import net.sourceforge.plantuml.code.TranscoderUtil; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.error.PSystemErrorPreprocessor; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.preproc2.PreprocessorMode; import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; @@ -57,6 +58,7 @@ import net.sourceforge.plantuml.version.Version; public class BlockUml { private final List data; + private List debug; private Diagram system; private final Defines localDefines; private final ISkinSimple skinParam; @@ -96,6 +98,9 @@ public class BlockUml { return result; } + private PreprocessorMode pmode = PreprocessorMode.V1_LEGACY; + private boolean preprocessorError; + public BlockUml(List strings, Defines defines, ISkinSimple skinParam, PreprocessorModeSet mode) { this.localDefines = defines; this.skinParam = skinParam; @@ -104,7 +109,12 @@ public class BlockUml { throw new IllegalArgumentException(); } if (mode != null && mode.getPreprocessorMode() == PreprocessorMode.V2_NEW_TIM) { - this.data = new TimLoader(mode.getImportedFiles(), defines).load(strings); + this.pmode = mode.getPreprocessorMode(); + final TimLoader timLoader = new TimLoader(mode.getImportedFiles(), defines, mode.getCharset()); + timLoader.load(strings); + this.data = timLoader.getResult(); + this.debug = timLoader.getDebug(); + this.preprocessorError = timLoader.isPreprocessorError(); } else { this.data = new ArrayList(strings); } @@ -139,7 +149,11 @@ public class BlockUml { public Diagram getDiagram() { if (system == null) { - system = new PSystemBuilder().createPSystem(skinParam, data); + if (preprocessorError) { + system = new PSystemErrorPreprocessor(data, debug); + } else { + system = new PSystemBuilder().createPSystem(skinParam, data); + } } return system; } diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java index 1cf84c1cb..6048abe71 100644 --- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -57,18 +57,20 @@ import net.sourceforge.plantuml.utils.StartUtils; public final class BlockUmlBuilder implements DefinitionsContainer { - private PreprocessorMode mode = PreprocessorMode.V1_LEGACY; + private PreprocessorMode mode = PreprocessorMode.V2_NEW_TIM; private final List blocks = new ArrayList(); private Set usedFiles = new HashSet(); private final UncommentReadLine reader2; private final Defines defines; private final ImportedFiles importedFiles; + private final String charset; public BlockUmlBuilder(List config, String charset, Defines defines, Reader reader, File newCurrentDir, String desc) throws IOException { ReadLineNumbered includer = null; this.defines = defines; + this.charset = charset; try { this.reader2 = new UncommentReadLine(new PreprocessorChangeModeReader(ReadLineReader.create(reader, desc), this)); @@ -159,4 +161,8 @@ public final class BlockUmlBuilder implements DefinitionsContainer { return importedFiles; } + public final String getCharset() { + return charset; + } + } diff --git a/src/net/sourceforge/plantuml/ColorParam.java b/src/net/sourceforge/plantuml/ColorParam.java index 66c80d66c..ff0f2d8ce 100644 --- a/src/net/sourceforge/plantuml/ColorParam.java +++ b/src/net/sourceforge/plantuml/ColorParam.java @@ -140,6 +140,8 @@ public enum ColorParam { nodeBorder(HtmlColorUtils.BLACK, ColorType.LINE), rectangleBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK), rectangleBorder(HtmlColorUtils.BLACK, ColorType.LINE), + archimateBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK), + archimateBorder(HtmlColorUtils.BLACK, ColorType.LINE), cardBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK), cardBorder(HtmlColorUtils.BLACK, ColorType.LINE), agentBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK), diff --git a/src/net/sourceforge/plantuml/CornerParam.java b/src/net/sourceforge/plantuml/CornerParam.java index 84cfd23a4..971c6b8b6 100644 --- a/src/net/sourceforge/plantuml/CornerParam.java +++ b/src/net/sourceforge/plantuml/CornerParam.java @@ -36,7 +36,7 @@ package net.sourceforge.plantuml; public enum CornerParam { - DEFAULT, diagramBorder, titleBorder, rectangle, component, card, agent; + DEFAULT, diagramBorder, titleBorder, rectangle, archimate, component, card, agent; public String getRoundKey() { if (this == DEFAULT) { diff --git a/src/net/sourceforge/plantuml/ErrorUml.java b/src/net/sourceforge/plantuml/ErrorUml.java index 7944ca0a6..82267a388 100644 --- a/src/net/sourceforge/plantuml/ErrorUml.java +++ b/src/net/sourceforge/plantuml/ErrorUml.java @@ -35,14 +35,11 @@ */ package net.sourceforge.plantuml; -import net.sourceforge.plantuml.suggest.SuggestEngineResult; -import net.sourceforge.plantuml.suggest.SuggestEngineStatus; public class ErrorUml { private final String error; private final ErrorUmlType type; - private SuggestEngineResult suggest; private final LineLocation lineLocation; public ErrorUml(ErrorUmlType type, String error, LineLocation lineLocation) { @@ -62,12 +59,12 @@ public class ErrorUml { @Override public int hashCode() { - return error.hashCode() + type.hashCode() + getPosition() + (suggest == null ? 0 : suggest.hashCode()); + return error.hashCode() + type.hashCode() + getPosition(); } @Override public String toString() { - return type.toString() + " " + getPosition() + " " + error + " " + suggest; + return type.toString() + " " + getPosition() + " " + error; } public final String getError() { @@ -86,16 +83,4 @@ public class ErrorUml { return lineLocation; } - public final SuggestEngineResult getSuggest() { - return suggest; - } - - public final boolean hasSuggest() { - return suggest != null && suggest.getStatus() == SuggestEngineStatus.ONE_SUGGESTION; - } - - public void setSuggest(SuggestEngineResult suggest) { - this.suggest = suggest; - } - } diff --git a/src/net/sourceforge/plantuml/FontParam.java b/src/net/sourceforge/plantuml/FontParam.java index 99821476a..13d2333e6 100644 --- a/src/net/sourceforge/plantuml/FontParam.java +++ b/src/net/sourceforge/plantuml/FontParam.java @@ -77,6 +77,7 @@ public enum FontParam { ENTITY(14, Font.PLAIN), // AGENT(14, Font.PLAIN), // RECTANGLE(14, Font.PLAIN), // + ARCHIMATE(14, Font.PLAIN), // CARD(14, Font.PLAIN), // NODE(14, Font.PLAIN), // DATABASE(14, Font.PLAIN), // @@ -110,6 +111,7 @@ public enum FontParam { ENTITY_STEREOTYPE(14, Font.ITALIC), // AGENT_STEREOTYPE(14, Font.ITALIC), // RECTANGLE_STEREOTYPE(14, Font.ITALIC), // + ARCHIMATE_STEREOTYPE(14, Font.ITALIC), // CARD_STEREOTYPE(14, Font.ITALIC), // NODE_STEREOTYPE(14, Font.ITALIC), // FOLDER_STEREOTYPE(14, Font.ITALIC), // diff --git a/src/net/sourceforge/plantuml/GeneratedImageImpl.java b/src/net/sourceforge/plantuml/GeneratedImageImpl.java index a3ab2592c..39e5ba2c2 100644 --- a/src/net/sourceforge/plantuml/GeneratedImageImpl.java +++ b/src/net/sourceforge/plantuml/GeneratedImageImpl.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml; import java.io.File; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.error.PSystemError; public class GeneratedImageImpl implements GeneratedImage { @@ -68,7 +69,7 @@ public class GeneratedImageImpl implements GeneratedImage { public int lineErrorRaw() { final Diagram system = blockUml.getDiagram(); if (system instanceof PSystemError) { - return ((PSystemError) system).getHigherErrorPosition2().getPosition(); + return ((PSystemError) system).getLineLocation().getPosition(); } return -1; } diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index d09186bd2..14e5422b1 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -73,6 +73,8 @@ public interface ISkinParam extends ISkinSimple { public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue); + public HorizontalAlignment getStereotypeAlignment(); + public int getCircledCharacterRadius(); public char getCircledCharacter(Stereotype stereotype); diff --git a/src/net/sourceforge/plantuml/LineParam.java b/src/net/sourceforge/plantuml/LineParam.java index e28c93548..bebacc0e3 100644 --- a/src/net/sourceforge/plantuml/LineParam.java +++ b/src/net/sourceforge/plantuml/LineParam.java @@ -55,6 +55,7 @@ public enum LineParam { titleBorder, diagramBorder, rectangleBorder, + archimateBorder, componentBorder, cardBorder, agentBorder, diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 3c2a2aa84..03de86db0 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -63,6 +63,8 @@ import net.sourceforge.plantuml.eggs.PSystemColorsFactory; import net.sourceforge.plantuml.eggs.PSystemEggFactory; import net.sourceforge.plantuml.eggs.PSystemRIPFactory; import net.sourceforge.plantuml.eggs.PSystemWelcomeFactory; +import net.sourceforge.plantuml.error.PSystemError; +import net.sourceforge.plantuml.error.PSystemErrorUtils; import net.sourceforge.plantuml.flowdiagram.FlowDiagramFactory; import net.sourceforge.plantuml.font.PSystemListFontsFactory; import net.sourceforge.plantuml.help.HelpFactory; @@ -100,15 +102,15 @@ public class PSystemBuilder { final DiagramType type = DiagramType.getTypeFromArobaseStart(strings2.get(0).getString()); final UmlSource umlSource = new UmlSource(strings2, type == DiagramType.UML); - // int cpt = 0; for (StringLocated s : strings2) { if (s.getPreprocessorError() != null) { + // Dead code : should not append Log.error("Preprocessor Error: " + s.getPreprocessorError()); final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, s.getPreprocessorError(), /* cpt */ s.getLocation()); - return new PSystemError(umlSource, err, Collections. emptyList()); + // return PSystemErrorUtils.buildV1(umlSource, err, Collections. emptyList()); + return PSystemErrorUtils.buildV2(umlSource, err, Collections. emptyList(), strings2); } - // cpt++; } final DiagramType diagramType = umlSource.getDiagramType(); @@ -126,7 +128,7 @@ public class PSystemBuilder { errors.add((PSystemError) sys); } - final PSystemError err = PSystemError.merge(errors); + final PSystemError err = PSystemErrorUtils.merge(errors); result = err; return err; } finally { diff --git a/src/net/sourceforge/plantuml/Pipe.java b/src/net/sourceforge/plantuml/Pipe.java index bc8dfcee6..fbfda6801 100644 --- a/src/net/sourceforge/plantuml/Pipe.java +++ b/src/net/sourceforge/plantuml/Pipe.java @@ -44,6 +44,7 @@ import java.util.List; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramDescription; +import net.sourceforge.plantuml.error.PSystemError; import net.sourceforge.plantuml.preproc.Defines; public class Pipe { diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index d0fe5fe8a..c55465dea 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -550,6 +550,15 @@ public class SkinParam implements ISkinParam { return result; } + public HorizontalAlignment getStereotypeAlignment() { + final String value = getValue("stereotypealignment"); + final HorizontalAlignment result = HorizontalAlignment.fromString(value); + if (result == null) { + return HorizontalAlignment.CENTER; + } + return result; + } + private String getArg(String value, int i) { if (value == null) { return null; diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java index 9375473a1..c09d5adfe 100644 --- a/src/net/sourceforge/plantuml/SkinParamDelegator.java +++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java @@ -317,5 +317,10 @@ public class SkinParamDelegator implements ISkinParam { public Map values() { return skinParam.values(); } + + public HorizontalAlignment getStereotypeAlignment() { + return skinParam.getStereotypeAlignment(); + } + } diff --git a/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java b/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java index 31ab739b4..337f03d4e 100644 --- a/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java +++ b/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java @@ -52,6 +52,7 @@ import java.util.List; import java.util.Set; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.error.PSystemError; import net.sourceforge.plantuml.preproc.FileWithSuffix; public abstract class SourceFileReaderAbstract { diff --git a/src/net/sourceforge/plantuml/StdrptPipe0.java b/src/net/sourceforge/plantuml/StdrptPipe0.java index 835dad54a..7254bb1b2 100644 --- a/src/net/sourceforge/plantuml/StdrptPipe0.java +++ b/src/net/sourceforge/plantuml/StdrptPipe0.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml; import java.io.PrintStream; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.error.PSystemError; public class StdrptPipe0 implements Stdrpt { @@ -45,7 +46,7 @@ public class StdrptPipe0 implements Stdrpt { if (sys instanceof PSystemError) { final PSystemError err = (PSystemError) sys; output.println("ERROR"); - output.println(err.getHigherErrorPosition2().getPosition()); + output.println(err.getLineLocation().getPosition()); for (ErrorUml er : err.getErrorsUml()) { output.println(er.getError()); } diff --git a/src/net/sourceforge/plantuml/StdrptV1.java b/src/net/sourceforge/plantuml/StdrptV1.java index b6edfbe4f..83f0015d0 100644 --- a/src/net/sourceforge/plantuml/StdrptV1.java +++ b/src/net/sourceforge/plantuml/StdrptV1.java @@ -40,6 +40,7 @@ import java.io.PrintStream; import net.sourceforge.plantuml.command.PSystemAbstractFactory; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.eggs.PSystemWelcome; +import net.sourceforge.plantuml.error.PSystemError; public class StdrptV1 implements Stdrpt { @@ -58,7 +59,7 @@ public class StdrptV1 implements Stdrpt { output.println("status=NO_DATA"); } else { output.println("status=ERROR"); - output.println("lineNumber=" + err.getHigherErrorPosition2().getPosition()); + output.println("lineNumber=" + err.getLineLocation().getPosition()); for (ErrorUml er : err.getErrorsUml()) { output.println("label=" + er.getError()); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java index b37d04e53..fd37e2388 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -262,7 +262,7 @@ public class ActivityDiagram3 extends UmlDiagram { } public void split() { - final InstructionSplit instructionSplit = new InstructionSplit(current(), nextLinkRenderer()); + final InstructionSplit instructionSplit = new InstructionSplit(current(), nextLinkRenderer(), swinlanes.getCurrentSwimlane()); setNextLinkRendererInternal(LinkRendering.none()); current().add(instructionSplit); setCurrent(instructionSplit); @@ -279,7 +279,7 @@ public class ActivityDiagram3 extends UmlDiagram { public CommandExecutionResult endSplit() { if (current() instanceof InstructionSplit) { - ((InstructionSplit) current()).endSplit(nextLinkRenderer()); + ((InstructionSplit) current()).endSplit(nextLinkRenderer(), swinlanes.getCurrentSwimlane()); setNextLinkRendererInternal(LinkRendering.none()); setCurrent(((InstructionSplit) current()).getParent()); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java index e911a1c89..7448c350d 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java @@ -155,15 +155,6 @@ public class InstructionList extends WithNote implements Instruction, Instructio public Swimlane getSwimlaneIn() { return defaultSwimlane; - // final Set swimlanes = getSwimlanes(); - // if (swimlanes.size() == 0) { - // return null; - // } - // if (swimlanes.size() == 1) { - // return swimlanes.iterator().next(); - // } - // System.err.println("foo1="+getClass()); - // return all.get(0).getSwimlaneIn(); } public Swimlane getSwimlaneOut() { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java index c311885d3..c6abe32ea 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java @@ -52,16 +52,20 @@ public class InstructionSplit implements Instruction { private final List splits = new ArrayList(); private final Instruction parent; private final LinkRendering inlinkRendering; + private final Swimlane swimlaneIn; + private Swimlane swimlaneOut; - public InstructionSplit(Instruction parent, LinkRendering inlinkRendering) { + public InstructionSplit(Instruction parent, LinkRendering inlinkRendering, Swimlane swimlane) { this.parent = parent; - this.splits.add(new InstructionList()); + this.swimlaneIn = swimlane; + + this.splits.add(new InstructionList(swimlane)); this.inlinkRendering = inlinkRendering; if (inlinkRendering == null) { throw new IllegalArgumentException(); } } - + public boolean containsBreak() { for (InstructionList split : splits) { if (split.containsBreak()) { @@ -71,7 +75,6 @@ public class InstructionSplit implements Instruction { return false; } - private InstructionList getLast() { return splits.get(splits.size() - 1); } @@ -96,14 +99,15 @@ public class InstructionSplit implements Instruction { if (inlinkRendering != null) { getLast().setOutRendering(inlinkRendering); } - final InstructionList list = new InstructionList(); + final InstructionList list = new InstructionList(swimlaneIn); this.splits.add(list); } - public void endSplit(LinkRendering inlinkRendering) { + public void endSplit(LinkRendering inlinkRendering, Swimlane endSwimlane) { if (inlinkRendering != null) { getLast().setOutRendering(inlinkRendering); } + this.swimlaneOut = endSwimlane; } @@ -128,7 +132,8 @@ public class InstructionSplit implements Instruction { } public Swimlane getSwimlaneOut() { - return getLast().getSwimlaneOut(); + return swimlaneOut; + // return getLast().getSwimlaneOut(); } } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCase.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCase.java index 1b4911b57..0c79e6479 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCase.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCase.java @@ -43,8 +43,6 @@ import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Display; -import net.sourceforge.plantuml.graphic.HtmlColor; -import net.sourceforge.plantuml.graphic.color.ColorParser; public class CommandCase extends SingleLineCommand2 { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileGeometry.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileGeometry.java index 5ebc2655b..6c7bdf894 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileGeometry.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileGeometry.java @@ -48,6 +48,44 @@ public class FtileGeometry extends Dimension2D { private final double inY; private final double outY; + public Point2D getPointA() { + return new Point2D.Double(left, inY); + } + + public Point2D getPointIn() { + return new Point2D.Double(left, inY); + } + + public Point2D getPointB() { + if (outY == Double.MIN_NORMAL) { + throw new UnsupportedOperationException(); + } + return new Point2D.Double(width, (inY + outY) / 2); + } + + public Point2D getPointC() { + if (outY == Double.MIN_NORMAL) { + throw new UnsupportedOperationException(); + } + return new Point2D.Double(left, outY); + } + + public Point2D getPointD() { + if (outY == Double.MIN_NORMAL) { + throw new UnsupportedOperationException(); + } + return new Point2D.Double(0, (inY + outY) / 2); + } + + public Point2D getPointOut() { + if (outY == Double.MIN_NORMAL) { + throw new UnsupportedOperationException(); + } + return new Point2D.Double(left, outY); + } + + + public FtileGeometry(Dimension2D dim, double left, double inY) { this(dim.getWidth(), dim.getHeight(), left, inY); } @@ -86,17 +124,6 @@ public class FtileGeometry extends Dimension2D { return outY != Double.MIN_NORMAL; } - public Point2D getPointIn() { - return new Point2D.Double(left, inY); - } - - public Point2D getPointOut() { - if (outY == Double.MIN_NORMAL) { - throw new UnsupportedOperationException(); - } - return new Point2D.Double(left, outY); - } - public FtileGeometry withoutPointOut() { return new FtileGeometry(width, height, left, inY); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Snake.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Snake.java index 564b3049e..bf20b18be 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Snake.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Snake.java @@ -66,12 +66,11 @@ public class Snake implements UShape { private MergeStrategy mergeable = MergeStrategy.FULL; private Direction emphasizeDirection; private final HorizontalAlignment horizontalAlignment; - + public final void setIgnoreForCompression(boolean ignoreForCompression) { this.worm.setIgnoreForCompression(ignoreForCompression); } - public Snake transformX(CompressionTransform compressionTransform) { final Snake result = new Snake(startDecoration, horizontalAlignment, color, endDecoration); result.textBlock = this.textBlock; @@ -206,14 +205,19 @@ public class Snake implements UShape { final Dimension2D dim = textBlock.calculateDimension(stringBounder); double x = Math.max(pt1.getX(), pt2.getX()) + 4; final boolean zigzag = worm.getDirectionsCode().startsWith("DLD") || worm.getDirectionsCode().startsWith("DRD"); + double y = (pt1.getY() + pt2.getY()) / 2 - dim.getHeight() / 2; if (horizontalAlignment == HorizontalAlignment.CENTER && zigzag) { final Point2D pt3 = worm.get(2); x = (pt2.getX() + pt3.getX()) / 2 - dim.getWidth() / 2; } else if (horizontalAlignment == HorizontalAlignment.RIGHT && zigzag) { - // final Point2D pt3 = worm.get(2); x = Math.max(pt1.getX(), pt2.getX()) - dim.getWidth() - 4; + } else if (worm.getDirectionsCode().equals("RD")) { + x = Math.max(pt1.getX(), pt2.getX()); + y = (pt1.getY() + worm.get(2).getY()) / 2 - dim.getHeight() / 2; + } else if (worm.getDirectionsCode().equals("LD")) { + x = Math.min(pt1.getX(), pt2.getX()); + y = (pt1.getY() + worm.get(2).getY()) / 2 - dim.getHeight() / 2; } - final double y = (pt1.getY() + pt2.getY()) / 2 - dim.getHeight() / 2; return new Point2D.Double(x, y); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Worm.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Worm.java index 31aef25ef..911fd434b 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Worm.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Worm.java @@ -206,6 +206,12 @@ public class Worm implements Iterable { } public void addPoint(double x, double y) { + if (points.size() > 0) { + final Point2D last = getLast(); + if (last.getX() == x && last.getY() == y) { + return; + } + } this.points.add(new Point2D.Double(x, y)); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java index 8e027b31a..dee9622be 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java @@ -40,10 +40,8 @@ import java.util.List; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; -import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.activitydiagram3.Branch; import net.sourceforge.plantuml.activitydiagram3.LinkRendering; -import net.sourceforge.plantuml.activitydiagram3.ftile.Diamond; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactoryDelegator; @@ -51,20 +49,17 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.FtileMinWidth; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond.FtileSwitchNude; import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond.FtileSwitchWithDiamonds; -import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamond; +import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond.FtileSwitchWithOneLink; +import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond.FtileSwitchWithManyLinks; import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamondInside; -import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; -import net.sourceforge.plantuml.creole.Sheet; -import net.sourceforge.plantuml.creole.SheetBlock1; -import net.sourceforge.plantuml.creole.SheetBlock2; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlColorAndStyle; +import net.sourceforge.plantuml.graphic.Rainbow; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; -import net.sourceforge.plantuml.svek.ConditionStyle; public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator { @@ -93,7 +88,8 @@ public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator { // fcArrow, topInlinkRendering, afterEndwhile, fcTest); // return createNude(swimlane, branches); - return createWithDiamonds(swimlane, branches, labelTest); + // return createWithDiamonds(swimlane, branches, labelTest); + return createWithLinks(swimlane, branches, labelTest); } private Ftile createNude(Swimlane swimlane, List branches) { @@ -111,7 +107,27 @@ public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator { } final Ftile diamond1 = getDiamond1(swimlane, branches.get(0), labelTest); final Ftile diamond2 = getDiamond2(swimlane, branches.get(0)); - return new FtileSwitchWithDiamonds(ftiles, swimlane, diamond1, diamond2, getStringBounder()); + + return new FtileSwitchWithDiamonds(ftiles, branches, swimlane, diamond1, diamond2, getStringBounder()); + } + + private Ftile createWithLinks(Swimlane swimlane, List branches, Display labelTest) { + final List ftiles = new ArrayList(); + for (Branch branch : branches) { + ftiles.add(new FtileMinWidth(branch.getFtile(), 30)); + } + final Ftile diamond1 = getDiamond1(swimlane, branches.get(0), labelTest); + final Ftile diamond2 = getDiamond2(swimlane, branches.get(0)); + final Rainbow arrowColor = HtmlColorAndStyle.build(skinParam()); + if (ftiles.size() == 1) { + final FtileSwitchWithOneLink result = new FtileSwitchWithOneLink(ftiles, branches, swimlane, diamond1, + diamond2, getStringBounder(), arrowColor); + return result.addLinks(); + } + final FtileSwitchWithManyLinks result = new FtileSwitchWithManyLinks(ftiles, branches, swimlane, diamond1, + diamond2, getStringBounder(), arrowColor); + return result.addLinks(); + } private Ftile getDiamond1(Swimlane swimlane, Branch branch0, Display test) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java index 5c1b0a7fa..1a1dce4bf 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java @@ -209,7 +209,7 @@ public class FtileGroup extends AbstractFtile { .withShadow(skinParam().shadowing(null)).withStroke(stroke).withCorner(roundCorner, 0); type.asBig(name, inner.skinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false), - TextBlockUtils.empty(0, 0), dimTotal.getWidth(), dimTotal.getHeight(), symbolContext).drawU(ug); + TextBlockUtils.empty(0, 0), dimTotal.getWidth(), dimTotal.getHeight(), symbolContext, skinParam().getStereotypeAlignment()).drawU(ug); final Dimension2D dimHeaderNote = headerNote.calculateDimension(stringBounder); headerNote.drawU(ug.apply(new UTranslate(dimTotal.getWidth() - dimHeaderNote.getWidth() - 10, diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java index b18d3de14..fd68b59c3 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java @@ -593,13 +593,22 @@ class FtileIfLongHorizontal extends AbstractFtile { for (Ftile couple : couples) { result = Dimension2DDouble.mergeLR(result, couple.calculateDimension(stringBounder)); } - final FtileGeometry dimTile2 = tile2.calculateDimension(stringBounder); + Dimension2D dimTile2 = tile2.calculateDimension(stringBounder); + dimTile2 = Dimension2DDouble.delta(dimTile2, 0, getDiamondsHeight(stringBounder) / 2); result = Dimension2DDouble.mergeLR(result, dimTile2); result = Dimension2DDouble.delta(result, xSeparation * couples.size(), 100); return new FtileGeometry(result, result.getWidth() / 2, 0); } + private double getDiamondsHeight(StringBounder stringBounder) { + double height = 0; + for (Ftile diamond : diamonds) { + height = Math.max(height, diamond.calculateDimension(stringBounder).getHeight()); + } + return height; + } + @Override protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) { final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java index af93efe5f..1cf69898a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java @@ -70,6 +70,7 @@ import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.Rainbow; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -118,8 +119,8 @@ class FtileWhile extends AbstractFtile { ConditionStyle conditionStyle, FontConfiguration fcTest, Instruction specialOut) { final TextBlock yesTb = yes.create(fontArrow, HorizontalAlignment.LEFT, ftileFactory.skinParam()); - final TextBlock testTb = test.create(fcTest, - whileBlock.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT), ftileFactory.skinParam()); + final TextBlock testTb = test.isWhite() ? TextBlockUtils.empty(0, 0) : test.create(fcTest, whileBlock + .skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT), ftileFactory.skinParam()); final TextBlock out = out2.create(fontArrow, HorizontalAlignment.LEFT, ftileFactory.skinParam()); final Ftile diamond1; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileIfWithLinks.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileIfWithLinks.java index f628c17b0..c6b55621a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileIfWithLinks.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileIfWithLinks.java @@ -119,18 +119,15 @@ public class FtileIfWithLinks extends FtileIfWithDiamonds { private Point2D getP1(StringBounder stringBounder) { final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder); - final double diamondWidth = dimDiamond1.getWidth(); - final double x; + final Point2D pt; if (getFtile2() == tile1) { - x = 0; + pt = dimDiamond1.getPointD(); } else if (getFtile2() == tile2) { - x = diamondWidth; + pt = dimDiamond1.getPointB(); } else { throw new IllegalStateException(); } - final double half = (dimDiamond1.getOutY() - dimDiamond1.getInY()) / 2; - return getTranslateDiamond1(stringBounder) - .getTranslated(new Point2D.Double(x, dimDiamond1.getInY() + half)); + return getTranslateDiamond1(stringBounder).getTranslated(pt); } private Point2D getP2(final StringBounder stringBounder) { @@ -214,18 +211,16 @@ public class FtileIfWithLinks extends FtileIfWithDiamonds { } private Point2D getP2(StringBounder stringBounder) { - final Dimension2D dimDiamond2 = diamond2.calculateDimension(stringBounder); - final double diamondWidth = dimDiamond2.getWidth(); - final double x; + final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder); + final Point2D pt; if (getFtile1() == tile1) { - x = 0; + pt = dimDiamond2.getPointD(); } else if (getFtile1() == tile2) { - x = diamondWidth; + pt = dimDiamond2.getPointB(); } else { throw new IllegalStateException(); } - return getTranslateDiamond2(stringBounder) - .getTranslated(new Point2D.Double(x, dimDiamond2.getHeight() / 2)); + return getTranslateDiamond2(stringBounder).getTranslated(pt); } private UTranslate translate(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchNude.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchNude.java index 70b0a4d9c..094191b59 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchNude.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchNude.java @@ -36,7 +36,6 @@ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond; import java.awt.geom.Dimension2D; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -91,12 +90,12 @@ public class FtileSwitchNude extends FtileDimensionMemoize { @Override public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) { if (tiles.contains(child)) { - return getTranslate1(child, stringBounder); + return getTranslateNude(child, stringBounder); } throw new UnsupportedOperationException(); } - private UTranslate getTranslate1(Ftile tile, StringBounder stringBounder) { + protected UTranslate getTranslateNude(Ftile tile, StringBounder stringBounder) { double x1 = 0; for (Ftile candidate : tiles) { final FtileGeometry dim1 = candidate.calculateDimension(stringBounder); @@ -111,7 +110,7 @@ public class FtileSwitchNude extends FtileDimensionMemoize { public void drawU(UGraphic ug) { final StringBounder stringBounder = ug.getStringBounder(); for (Ftile tile : tiles) { - ug.apply(getTranslate1(tile, stringBounder)).draw(tile); + ug.apply(getTranslateNude(tile, stringBounder)).draw(tile); } } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithDiamonds.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithDiamonds.java index 1e54321cb..a6ea5a6cc 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithDiamonds.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithDiamonds.java @@ -35,18 +35,21 @@ */ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond; -import java.awt.geom.Dimension2D; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.activitydiagram3.Branch; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.ugraphic.UChange; +import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -54,10 +57,12 @@ public class FtileSwitchWithDiamonds extends FtileSwitchNude { protected final Ftile diamond1; protected final Ftile diamond2; + protected final List branches; - public FtileSwitchWithDiamonds(List tiles, Swimlane in, Ftile diamond1, Ftile diamond2, - StringBounder stringBounder) { + public FtileSwitchWithDiamonds(List tiles, List branches, Swimlane in, Ftile diamond1, + Ftile diamond2, StringBounder stringBounder) { super(tiles, in); + this.branches = branches; this.diamond1 = diamond1; this.diamond2 = diamond2; } @@ -96,11 +101,11 @@ public class FtileSwitchWithDiamonds extends FtileSwitchNude { final StringBounder stringBounder = ug.getStringBounder(); ug.apply(getTranslateDiamond1(stringBounder)).draw(diamond1); - super.drawU(ug.apply(getUTranslateMain(stringBounder))); + super.drawU(ug.apply(getTranslateMain(stringBounder))); ug.apply(getTranslateDiamond2(stringBounder)).draw(diamond2); } - private UChange getUTranslateMain(StringBounder stringBounder) { + protected UTranslate getTranslateMain(StringBounder stringBounder) { final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder); return new UTranslate(0, dimDiamond1.getHeight() + getYdelta1a(stringBounder)); } @@ -121,4 +126,15 @@ public class FtileSwitchWithDiamonds extends FtileSwitchNude { return new UTranslate(x2, y2); } + protected UTranslate getTranslateOf(Ftile tile, StringBounder stringBounder) { + return getTranslateNude(tile, stringBounder).compose(getTranslateMain(stringBounder)); + } + + protected TextBlock getLabelPositive(Branch branch) { + final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ARROW, null); + return branch.getLabelPositive().create(fcArrow, HorizontalAlignment.LEFT, skinParam(), CreoleMode.SIMPLE_LINE); + } + + + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java new file mode 100644 index 000000000..cb43d0b09 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java @@ -0,0 +1,280 @@ +/* ======================================================================== + * 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.activitydiagram3.ftile.vcompact.cond; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram3.Branch; +import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractConnection; +import net.sourceforge.plantuml.activitydiagram3.ftile.Arrows; +import net.sourceforge.plantuml.activitydiagram3.ftile.Connection; +import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; +import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; +import net.sourceforge.plantuml.activitydiagram3.ftile.FtileUtils; +import net.sourceforge.plantuml.activitydiagram3.ftile.Snake; +import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; +import net.sourceforge.plantuml.graphic.Rainbow; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds { + + private final Rainbow arrowColor; + private final double margin = 10; + + public FtileSwitchWithManyLinks(List tiles, List branches, Swimlane in, Ftile diamond1, + Ftile diamond2, StringBounder stringBounder, Rainbow arrowColor) { + super(tiles, branches, in, diamond1, diamond2, stringBounder); + this.arrowColor = arrowColor; + } + + class ConnectionHorizontalThenVertical extends AbstractConnection { + + private final Branch branch; + + public ConnectionHorizontalThenVertical(Ftile tile, Branch branch) { + super(diamond1, tile); + this.branch = branch; + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Point2D p1 = getP1(stringBounder); + final Point2D p2 = getP2(stringBounder); + final double x1 = p1.getX(); + final double y1 = p1.getY(); + final double x2 = p2.getX(); + final double y2 = p2.getY(); + + final Snake snake = new Snake(null, arrowHorizontalAlignment(), arrowColor, Arrows.asToDown()); + snake.setLabel(getLabelPositive(branch)); + snake.addPoint(x1, y1); + snake.addPoint(x2, y1); + snake.addPoint(x2, y2); + + ug.draw(snake); + } + + private Point2D getP1(StringBounder stringBounder) { + final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder); + final Point2D pt; + if (getFtile2() == tiles.get(0)) { + pt = dimDiamond1.getPointD(); + } else if (getFtile2() == tiles.get(tiles.size() - 1)) { + pt = dimDiamond1.getPointB(); + } else { + throw new IllegalStateException(); + } + return getTranslateDiamond1(stringBounder).getTranslated(pt); + } + + private Point2D getP2(final StringBounder stringBounder) { + return getTranslateOf(getFtile2(), stringBounder).getTranslated( + getFtile2().calculateDimension(stringBounder).getPointIn()); + } + + } + + class ConnectionVerticalThenHorizontal extends AbstractConnection { + + public ConnectionVerticalThenHorizontal(Ftile tile) { + super(tile, diamond2); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final FtileGeometry geo = getFtile1().calculateDimension(stringBounder); + if (geo.hasPointOut() == false) { + return; + } + final Point2D p1 = getP1(stringBounder); + final Point2D p2 = getP2(stringBounder); + + final double x1 = p1.getX(); + final double y1 = p1.getY(); + final double x2 = p2.getX(); + final double y2 = p2.getY(); + + final UPolygon arrow = x2 > x1 ? Arrows.asToRight() : Arrows.asToLeft(); + final Snake snake = new Snake(arrowHorizontalAlignment(), arrowColor, arrow); + snake.addPoint(x1, y1); + snake.addPoint(x1, y2); + snake.addPoint(x2, y2); + + ug.draw(snake); + } + + private Point2D getP1(StringBounder stringBounder) { + return getTranslateOf(getFtile1(), stringBounder).getTranslated( + getFtile1().calculateDimension(stringBounder).getPointOut()); + } + + private Point2D getP2(StringBounder stringBounder) { + final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder); + final Point2D pt; + if (getFtile1() == tiles.get(0)) { + pt = dimDiamond2.getPointD(); + } else if (getFtile1() == tiles.get(tiles.size() - 1)) { + pt = dimDiamond2.getPointB(); + } else { + throw new IllegalStateException(); + } + return getTranslateDiamond2(stringBounder).getTranslated(pt); + + } + + } + + protected UTranslate getTranslateOf(Ftile tile, StringBounder stringBounder) { + return getTranslateNude(tile, stringBounder).compose(getTranslateMain(stringBounder)); + + } + + class ConnectionVerticalTop extends AbstractConnection { + + private final Branch branch; + + public ConnectionVerticalTop(Ftile tile, Branch branch) { + super(diamond1, tile); + this.branch = branch; + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder); + final UTranslate translateDiamond1 = getTranslateDiamond1(stringBounder); + final Point2D p1b = translateDiamond1.getTranslated(dimDiamond1.getPointB()); + final Point2D p1c = translateDiamond1.getTranslated(dimDiamond1.getPointC()); + final Point2D p1d = translateDiamond1.getTranslated(dimDiamond1.getPointD()); + + final Point2D p2 = getP2(stringBounder); + final double x2 = p2.getX(); + final double y2 = p2.getY(); + + final Snake snake = new Snake(null, arrowHorizontalAlignment(), arrowColor, Arrows.asToDown()); + snake.setLabel(getLabelPositive(branch)); + if (x2 < p1d.getX() - margin || x2 > p1b.getX() + margin) { + snake.addPoint(x2, p1d.getY()); + snake.addPoint(x2, y2); + } else { + final double x1 = p1c.getX(); + final double y1 = p1c.getY(); + + final double ym = (y1 * 2 + y2) / 3; + snake.addPoint(x1, y1); + snake.addPoint(x1, ym); + snake.addPoint(x2, ym); + snake.addPoint(x2, y2); + } + ug.draw(snake); + } + + private Point2D getP2(final StringBounder stringBounder) { + return getTranslateOf(getFtile2(), stringBounder).getTranslated( + getFtile2().calculateDimension(stringBounder).getPointIn()); + } + + } + + class ConnectionVerticalBottom extends AbstractConnection { + + public ConnectionVerticalBottom(Ftile tile) { + super(tile, diamond2); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Point2D p1 = getP1(stringBounder); + final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder); + final UTranslate translateDiamond2 = getTranslateDiamond2(stringBounder); + final Point2D p2a = translateDiamond2.getTranslated(dimDiamond2.getPointA()); + final Point2D p2b = translateDiamond2.getTranslated(dimDiamond2.getPointB()); + final Point2D p2d = translateDiamond2.getTranslated(dimDiamond2.getPointD()); + + final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder); + final UTranslate translateDiamond1 = getTranslateDiamond1(stringBounder); + final Point2D p1b = translateDiamond1.getTranslated(dimDiamond1.getPointB()); + final Point2D p1c = translateDiamond1.getTranslated(dimDiamond1.getPointC()); + final Point2D p1d = translateDiamond1.getTranslated(dimDiamond1.getPointD()); + + final double x1 = p1.getX(); + final double y1 = p1.getY(); + final double x2 = p2a.getX(); + final double y2 = p2a.getY(); + + final double ym = (y1 + y2) / 2; + + final Snake snake = new Snake(null, arrowHorizontalAlignment(), arrowColor, Arrows.asToDown()); + + if (x1 < p1d.getX() - margin || x1 > p1b.getX() + margin) { + snake.addPoint(x1, y1); + snake.addPoint(x1, p2d.getY()); + } else { + snake.addPoint(x1, y1); + snake.addPoint(x1, ym); + snake.addPoint(x2, ym); + snake.addPoint(x2, y2); + } + + ug.draw(snake); + } + + private Point2D getP1(StringBounder stringBounder) { + return getTranslateOf(getFtile1(), stringBounder).getTranslated( + getFtile1().calculateDimension(stringBounder).getPointOut()); + } + + } + + public Ftile addLinks() { + final List conns = new ArrayList(); + conns.add(new ConnectionHorizontalThenVertical(tiles.get(0), branches.get(0))); + conns.add(new ConnectionHorizontalThenVertical(tiles.get(tiles.size() - 1), branches.get(tiles.size() - 1))); + conns.add(new ConnectionVerticalThenHorizontal(tiles.get(0))); + conns.add(new ConnectionVerticalThenHorizontal(tiles.get(tiles.size() - 1))); + for (int i = 1; i < tiles.size() - 1; i++) { + conns.add(new ConnectionVerticalTop(tiles.get(i), branches.get(i))); + conns.add(new ConnectionVerticalBottom(tiles.get(i))); + } + + return FtileUtils.addConnection(this, conns); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithOneLink.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithOneLink.java new file mode 100644 index 000000000..eaec448b3 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithOneLink.java @@ -0,0 +1,150 @@ +/* ======================================================================== + * 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.activitydiagram3.ftile.vcompact.cond; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.activitydiagram3.Branch; +import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractConnection; +import net.sourceforge.plantuml.activitydiagram3.ftile.Arrows; +import net.sourceforge.plantuml.activitydiagram3.ftile.Connection; +import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; +import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; +import net.sourceforge.plantuml.activitydiagram3.ftile.FtileUtils; +import net.sourceforge.plantuml.activitydiagram3.ftile.Snake; +import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.Rainbow; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class FtileSwitchWithOneLink extends FtileSwitchWithDiamonds { + + private final Rainbow arrowColor; + + public FtileSwitchWithOneLink(List tiles, List branches, Swimlane in, Ftile diamond1, + Ftile diamond2, StringBounder stringBounder, Rainbow arrowColor) { + super(tiles, branches, in, diamond1, diamond2, stringBounder); + this.arrowColor = arrowColor; + } + + class ConnectionVerticalTop extends AbstractConnection { + + private final Branch branch; + + public ConnectionVerticalTop(Ftile tile, Branch branch) { + super(diamond1, tile); + this.branch = branch; + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Point2D p1 = getP1(stringBounder); + final Point2D p2 = getP2(stringBounder); + final double x1 = p1.getX(); + final double y1 = p1.getY(); + final double x2 = p2.getX(); + final double y2 = p2.getY(); + + final Snake snake = new Snake(null, arrowHorizontalAlignment(), arrowColor, Arrows.asToDown()); + snake.setLabel(getLabelPositive(branch)); + // snake.addPoint(x1, y1); + snake.addPoint(x2, y1); + snake.addPoint(x2, y2); + + ug.draw(snake); + } + + private Point2D getP1(StringBounder stringBounder) { + final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder); + return getTranslateDiamond1(stringBounder).getTranslated(dimDiamond1.getPointC()); + } + + private Point2D getP2(final StringBounder stringBounder) { + return getTranslateOf(getFtile2(), stringBounder).getTranslated( + getFtile2().calculateDimension(stringBounder).getPointIn()); + } + } + + class ConnectionVerticalBottom extends AbstractConnection { + + public ConnectionVerticalBottom(Ftile tile) { + super(tile, diamond2); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Point2D p1 = getP1(stringBounder); + final Point2D p2 = getP2(stringBounder); + final double x1 = p1.getX(); + final double y1 = p1.getY(); + final double x2 = p2.getX(); + final double y2 = p2.getY(); + + final Snake snake = new Snake(null, arrowHorizontalAlignment(), arrowColor, Arrows.asToDown()); + // snake.addPoint(x1, y1); + snake.addPoint(x2, y1); + snake.addPoint(x2, y2); + + ug.draw(snake); + } + + private Point2D getP1(StringBounder stringBounder) { + return getTranslateOf(getFtile1(), stringBounder).getTranslated( + getFtile1().calculateDimension(stringBounder).getPointOut()); + } + + private Point2D getP2(StringBounder stringBounder) { + final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder); + return getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointA()); + } + } + + public Ftile addLinks() { + final List conns = new ArrayList(); + conns.add(new ConnectionVerticalTop(tiles.get(0), branches.get(0))); + conns.add(new ConnectionVerticalBottom(tiles.get(0))); + + return FtileUtils.addConnection(this, conns); + } + +} diff --git a/src/net/sourceforge/plantuml/command/BlocLines.java b/src/net/sourceforge/plantuml/command/BlocLines.java index 413f6a3c1..24114d8a6 100644 --- a/src/net/sourceforge/plantuml/command/BlocLines.java +++ b/src/net/sourceforge/plantuml/command/BlocLines.java @@ -48,7 +48,6 @@ import java.util.List; import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.LineLocationImpl; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.cucadiagram.Display; diff --git a/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java b/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java index 668edc11d..9c9c8e4fe 100644 --- a/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java @@ -35,14 +35,17 @@ */ package net.sourceforge.plantuml.command; -import net.sourceforge.plantuml.AbstractPSystem; +import java.util.List; + import net.sourceforge.plantuml.ErrorUml; import net.sourceforge.plantuml.ErrorUmlType; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.PSystemError; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.api.PSystemFactory; import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.core.UmlSource; +import net.sourceforge.plantuml.error.PSystemError; +import net.sourceforge.plantuml.error.PSystemErrorUtils; public abstract class PSystemAbstractFactory implements PSystemFactory { @@ -53,17 +56,20 @@ public abstract class PSystemAbstractFactory implements PSystemFactory { this.type = type; } - final protected AbstractPSystem buildEmptyError(UmlSource source, LineLocation lineLocation) { + final protected PSystemError buildEmptyError(UmlSource source, LineLocation lineLocation, + List trace) { final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, EMPTY_DESCRIPTION, /* 1, */lineLocation); - final PSystemError result = new PSystemError(source, err, null); + // final AbstractPSystemError result = PSystemErrorUtils.buildV1(source, err, null); + final PSystemError result = PSystemErrorUtils.buildV2(source, err, null, trace); result.setSource(source); return result; } - final protected PSystemError buildExecutionError(UmlSource source, String stringError, LineLocation lineLocation) { + final protected PSystemError buildExecutionError(UmlSource source, String stringError, + LineLocation lineLocation, List trace) { final ErrorUml err = new ErrorUml(ErrorUmlType.EXECUTION_ERROR, stringError, /* 1, */ lineLocation); - final PSystemError result = new PSystemError(source, err, null); + final PSystemError result = PSystemErrorUtils.buildV2(source, err, null, trace); result.setSource(source); return result; } diff --git a/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java b/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java index f3a4ef7cd..acd62283d 100644 --- a/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java @@ -38,11 +38,11 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.ErrorUml; import net.sourceforge.plantuml.ErrorUmlType; -import net.sourceforge.plantuml.PSystemError; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.core.UmlSource; +import net.sourceforge.plantuml.error.PSystemErrorUtils; import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.version.IteratorCounter2; @@ -80,7 +80,7 @@ public abstract class PSystemBasicFactory

extends PSy first = false; if (StartUtils.isArobaseEndDiagram(s.getString())) { if (source.getTotalLineCount() == 2 && source.isStartDef() == false) { - return buildEmptyError(source, s.getLocation()); + return buildEmptyError(source, s.getLocation(), it.getTrace()); } if (system != null) { system.setSource(source); @@ -90,7 +90,8 @@ public abstract class PSystemBasicFactory

extends PSy system = executeLine(system, s.getString()); if (system == null) { final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", s.getLocation()); - return new PSystemError(source, err, null); + // return PSystemErrorUtils.buildV1(source, err, null); + return PSystemErrorUtils.buildV2(source, err, null, it.getTrace()); } } if (system != null) { diff --git a/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java b/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java index 4c964f121..596e2db81 100644 --- a/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java @@ -38,11 +38,12 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.ErrorUml; import net.sourceforge.plantuml.ErrorUmlType; -import net.sourceforge.plantuml.PSystemError; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.core.UmlSource; +import net.sourceforge.plantuml.error.PSystemErrorUtils; import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.version.IteratorCounter2; @@ -61,7 +62,8 @@ public abstract class PSystemSingleLineFactory extends PSystemAbstractFactory { } final IteratorCounter2 it = source.iterator2(); if (source.isEmpty()) { - return buildEmptyError(source, it.peek().getLocation()); + final LineLocation location = it.next().getLocation(); + return buildEmptyError(source, location, it.getTrace()); } final StringLocated startLine = it.next(); @@ -70,17 +72,17 @@ public abstract class PSystemSingleLineFactory extends PSystemAbstractFactory { } if (it.hasNext() == false) { - return buildEmptyError(source, startLine.getLocation()); + return buildEmptyError(source, startLine.getLocation(), it.getTrace()); } final StringLocated s = it.next(); if (StartUtils.isArobaseEndDiagram(s.getString())) { - return buildEmptyError(source, s.getLocation()); + return buildEmptyError(source, s.getLocation(), it.getTrace()); } final AbstractPSystem sys = executeLine(s.getString()); if (sys == null) { - final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", - /* it.currentNum() - 1, */s.getLocation()); - return new PSystemError(source, err, null); + final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", s.getLocation()); + // return PSystemErrorUtils.buildV1(source, err, null); + return PSystemErrorUtils.buildV2(source, err, null, it.getTrace()); } sys.setSource(source); return sys; diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java index 8959e003d..5e03c0805 100644 --- a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java @@ -36,11 +36,11 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.PSystemError; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.error.PSystemError; public abstract class SingleLineCommand2 implements Command { diff --git a/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java b/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java index 8edabaa00..37319acfa 100644 --- a/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java +++ b/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java @@ -43,7 +43,7 @@ import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.ErrorUml; import net.sourceforge.plantuml.ErrorUmlType; -import net.sourceforge.plantuml.PSystemError; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.classdiagram.command.CommandHideShowByGender; @@ -51,6 +51,8 @@ import net.sourceforge.plantuml.classdiagram.command.CommandHideShowByVisibility import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.core.UmlSource; +import net.sourceforge.plantuml.error.PSystemError; +import net.sourceforge.plantuml.error.PSystemErrorUtils; import net.sourceforge.plantuml.sequencediagram.command.CommandSkin; import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.version.IteratorCounter2; @@ -76,7 +78,8 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory { } if (source.isEmpty()) { - return buildEmptyError(source, startLine.getLocation()); + it.next(); + return buildEmptyError(source, startLine.getLocation(), it.getTrace()); } AbstractPSystem sys = createEmptyDiagram(); @@ -87,10 +90,12 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory { } final String err = sys.checkFinalError(); if (err != null) { - return buildExecutionError(source, err, it.peek().getLocation()); + final LineLocation location = it.next().getLocation(); + return buildExecutionError(source, err, location, it.getTrace()); } if (source.getTotalLineCount() == 2) { - return buildEmptyError(source, it.peek().getLocation()); + final LineLocation location = it.next().getLocation(); + return buildEmptyError(source, location, it.getTrace()); } sys.makeDiagramReady(); if (sys.isOk() == false) { @@ -113,14 +118,15 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory { final Step step = getCandidate(it); if (step == null) { final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", it.peek().getLocation()); - return new PSystemError(source, err, null); + it.next(); + return PSystemErrorUtils.buildV2(source, err, null, it.getTrace()); } final CommandExecutionResult result = sys.executeCommand(step.command, step.blocLines); if (result.isOk() == false) { final ErrorUml err = new ErrorUml(ErrorUmlType.EXECUTION_ERROR, result.getError(), ((StringLocated) step.blocLines.getFirst499()).getLocation()); - sys = new PSystemError(source, err, result.getDebugLines()); + sys = PSystemErrorUtils.buildV2(source, err, result.getDebugLines(), it.getTrace()); } if (result.getNewDiagram() != null) { sys = result.getNewDiagram(); diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java index 97cc403d1..f658dcae0 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java @@ -35,6 +35,8 @@ */ package net.sourceforge.plantuml.command.note.sequence; +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; @@ -51,6 +53,7 @@ import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.color.ColorParser; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.Colors; @@ -65,7 +68,11 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF return new RegexConcat( // new RegexLeaf("^"), // new RegexLeaf("VMERGE", "(/)?[%s]*"), // - new RegexLeaf("STYLE", "(note|hnote|rnote)[%s]+over[%s]+"), // + new RegexLeaf("STYLE", "(note|hnote|rnote)"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("over[%s]+"), // new RegexLeaf("P1", "([\\p{L}0-9_.@]+|[%g][^%g]+[%g])[%s]*\\,[%s]*"), // new RegexLeaf("P2", "([\\p{L}0-9_.@]+|[%g][^%g]+[%g])[%s]*"), // color().getRegex(), // @@ -78,7 +85,11 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF return new RegexConcat( // new RegexLeaf("^"), // new RegexLeaf("VMERGE", "(/)?[%s]*"), // - new RegexLeaf("STYLE", "(note|hnote|rnote)[%s]+over[%s]+"), // + new RegexLeaf("STYLE", "(note|hnote|rnote)"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("over[%s]+"), // new RegexLeaf("P1", "([\\p{L}0-9_.@]+|[%g][^%g]+[%g])[%s]*\\,[%s]*"), // new RegexLeaf("P2", "([\\p{L}0-9_.@]+|[%g][^%g]+[%g])[%s]*"), // color().getRegex(), // @@ -87,17 +98,17 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF new RegexLeaf("NOTE", "(.*)"), // new RegexLeaf("$")); } - + private static ColorParser color() { return ColorParser.simpleColor(ColorType.BACK); } - public Command createSingleLine() { return new SingleLineCommand2(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final SequenceDiagram system, LineLocation location, RegexResult arg) { + protected CommandExecutionResult executeArg(final SequenceDiagram system, LineLocation location, + RegexResult arg) { final BlocLines strings = BlocLines.getWithNewlines(arg.get("NOTE", 0)); return executeInternal(system, arg, strings); @@ -135,9 +146,16 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF final boolean tryMerge = line0.get("VMERGE", 0) != null; final Display display = diagram.manageVariable(lines.toDisplay()); final Note note = new Note(p1, p2, display); - final Colors colors = color().getColor(line0, diagram.getSkinParam().getIHtmlColorSet()); + Colors colors = color().getColor(line0, diagram.getSkinParam().getIHtmlColorSet()); + final String stereotypeString = line0.get("STEREO", 0); + if (stereotypeString != null) { + final Stereotype stereotype = new Stereotype(stereotypeString); + colors = colors.applyStereotypeForNote(stereotype, diagram.getSkinParam(), FontParam.NOTE, + ColorParam.noteBackground, ColorParam.noteBorder); + } note.setColors(colors); - // note.setSpecificColorTOBEREMOVED(ColorType.BACK, diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0))); + // note.setSpecificColorTOBEREMOVED(ColorType.BACK, + // diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0))); note.setStyle(NoteStyle.getNoteStyle(line0.get("STYLE", 0))); if (line0.get("URL", 0) != null) { final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), ModeUrl.STRICT); diff --git a/src/net/sourceforge/plantuml/creole/CreoleMode.java b/src/net/sourceforge/plantuml/creole/CreoleMode.java index 7fb8a28e9..8100efde8 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleMode.java +++ b/src/net/sourceforge/plantuml/creole/CreoleMode.java @@ -36,6 +36,6 @@ package net.sourceforge.plantuml.creole; public enum CreoleMode { - FULL, SIMPLE_LINE; + FULL, SIMPLE_LINE, NO_CREOLE; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java index d0c8327f1..9e91940c5 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java @@ -452,8 +452,8 @@ public class Display implements Iterable { } public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple spriteContainer, CreoleMode modeSimpleLine) { - return create(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, modeSimpleLine, + ISkinSimple spriteContainer, CreoleMode creoleMode) { + return create(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode, null, null); } @@ -470,7 +470,7 @@ public class Display implements Iterable { } public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode modeSimpleLine, + ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode, UFont fontForStereotype, HtmlColor htmlColorForStereotype) { if (maxMessageSize == null) { throw new IllegalArgumentException(); @@ -492,12 +492,12 @@ public class Display implements Iterable { } } - return getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, modeSimpleLine); + return getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, creoleMode); } private TextBlock getCreole(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode modeSimpleLine) { - final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, modeSimpleLine) + ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode) { + final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode) .createSheet(this); final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize, spriteContainer == null ? 0 : spriteContainer.getPadding()); diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index f09d2f339..0141831ee 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -245,6 +245,9 @@ public class Stereotype implements CharSequence { if (isWithOOSymbol()) { return null; } + if (spriteName != null && spriteName.startsWith("archimate/")) { + return guillemet.manageGuillemet("<<" + spriteName.substring("archimate/".length()) + ">>"); + } return guillemet.manageGuillemet(label); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java index 9b495a057..fe9993620 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java @@ -132,33 +132,31 @@ public class GraphvizUtils { if (local != null) { return local; } - final String env = System.getProperty("PLANTUML_LIMIT_SIZE"); + final String env = getenv("PLANTUML_LIMIT_SIZE"); if (StringUtils.isNotEmpty(env) && env.matches("\\d+")) { return Integer.parseInt(env); } - final String getenv = System.getenv("PLANTUML_LIMIT_SIZE"); - if (StringUtils.isNotEmpty(getenv) && getenv.matches("\\d+")) { - return Integer.parseInt(getenv); - } return 4096; } public static String getenvDefaultConfigFilename() { - final String env = System.getProperty("PLANTUML_DEFAULT_CONFIG_FILENAME"); - if (StringUtils.isNotEmpty(env)) { - return env; - } - return System.getenv("PLANTUML_DEFAULT_CONFIG_FILENAME"); + return getenv("PLANTUML_DEFAULT_CONFIG_FILENAME"); } public static String getenvLogData() { - final String env = System.getProperty("PLANTUML_LOGDATA"); + return getenv("PLANTUML_LOGDATA"); + } + + public static String getenv(String name) { + final String env = System.getProperty(name); if (StringUtils.isNotEmpty(env)) { return env; } - return System.getenv("PLANTUML_LOGDATA"); + return System.getenv(name); } + + private static String dotVersion = null; public static String dotVersion() throws IOException, InterruptedException { diff --git a/src/net/sourceforge/plantuml/dedication/Dedications.java b/src/net/sourceforge/plantuml/dedication/Dedications.java index 3a7c3fd29..edb3139f6 100644 --- a/src/net/sourceforge/plantuml/dedication/Dedications.java +++ b/src/net/sourceforge/plantuml/dedication/Dedications.java @@ -51,6 +51,7 @@ public class Dedications { addNormal("Write your own dedication!", "dedication"); addNormal("linux_china", "linux_china"); addNormal("ARKBAN", "arkban"); + addNormal("Boundaries allow discipline to create true strength", "boundaries"); addCrypted("0", "pOhci6rKgPXw32AeYXhOpSY0suoauHq5VUSwFqHLHsLYgSO6WaJ7BW5vtHBAoU6ePbcW7d8Flx99MWjPSKQTDm00"); addCrypted("1", "LTxN3hdnhSJ515qcA7IQ841axt4GXfUd3n2wgNirYCdLnyX2360Gv1OEOnJ1-gwFzRW5B3HAqLBkR6Ge0WW_Z000"); } diff --git a/src/net/sourceforge/plantuml/dedication/boundaries.png b/src/net/sourceforge/plantuml/dedication/boundaries.png new file mode 100644 index 000000000..b989556e6 Binary files /dev/null and b/src/net/sourceforge/plantuml/dedication/boundaries.png differ diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java index f52e18381..335fed437 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java @@ -101,8 +101,8 @@ public class CommandArchimate extends SingleLineCommand2 { final Code code = Code.of(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeRaw)); final String icon = arg.getLazzy("STEREOTYPE", 0); - final IEntity entity = diagram.getOrCreateLeaf(code, LeafType.DESCRIPTION, USymbol.RECTANGLE); - + final IEntity entity = diagram.getOrCreateLeaf(code, LeafType.DESCRIPTION, USymbol.ARCHIMATE); + final String displayRaw = arg.getLazzy("DISPLAY", 0); String display = displayRaw; @@ -112,7 +112,7 @@ public class CommandArchimate extends SingleLineCommand2 { display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(display); entity.setDisplay(Display.getWithNewlines(display)); - entity.setUSymbol(USymbol.RECTANGLE); + entity.setUSymbol(USymbol.ARCHIMATE); if (icon != null) { entity.setStereotype(new Stereotype("<<$archimate/" + icon + ">>", diagram.getSkinParam() .getCircledCharacterRadius(), diagram.getSkinParam().getFont(null, false, @@ -124,5 +124,4 @@ public class CommandArchimate extends SingleLineCommand2 { return CommandExecutionResult.ok(); } - } diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index dc5121d98..81187d210 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -70,23 +70,24 @@ public class PSystemDonors extends AbstractPSystem { private static final int COLS = 6; private static final int FREE_LINES = 6; - - public static final String DONORS = "6nC90AmEEBmtNeGqQuvtvvyfOnYjY14ipnEA4uiuxGR47-3Ujh6l87u5mINjNXY1P6bpXlCCebWGDPxr" - + "KuTjRlPNQ4jzbOnnKnDcmWH88JoNxPv-tYvLP9GWfehjjqnexsy_BjGXhHM2At1JEVztQO1veO0qJgTu" - + "29S3r7yAbjuekTPi_jATxOLcRJPqN81ADTfOiwDOi-L3HEbheJ6HsMkCWcoRQyUUKV8enbSYnLeRMs2L" - + "anOKQcCunITQ3_zH2sZIcbr3UhQ0OXaf6itRlZRs7PoVmQ0HmgnqnA3iKEBGNM2iKD-e8KnAi20tYcbi" - + "9END4pL2EA32B_oZ92bd3raPPTY0CDi31Qn-JH28PrD12MTxNWCAzs2BXWPBTMvPwIxt3yDJeImQhWKT" - + "PWvoWLG0UHDq8P-hprpIk8rDCSEBxiPuzKr2tcJd-UFDWxxfj34mVkuUcYdBSg3QUaZXbEiOlpewvAU6" - + "ZEpzfexOPWdX-MqkJFlI0fqVG2-rXednD-UNXMI8Z2breQVEwPDzYa1vPIaiUXLJNWlzeilLRI2UHmyM" - + "s5HVvrfPmGvTcTWDVK8hdCCwN-1K3VNFGwwwZa_1DM6tUzkKCsbpgVX_wvPc9ka1EcYYZT3L4YDFtxIg" - + "5vCXWfT17uRS0d83gY-JH-Lb-P3usXzGU4iYWIfjpcY_KPanNt9OH7ZXlJDLF01cDubyGLWyI0_YEe7U" - + "XYgRwB2xVa-Jac7JniovKIgMkmvZL3wcavMBxjLSu2iDmx9i3ktMVi1Hm0FOQLvr5dUj0fosz9vOB8qd" - + "6KZNCAS6qdvKsVUq9TsNEaPcMM_nhYxnRcu7VnwwV63V5YqmhNGTiY0qRngHKxSuprE3wczFo0PjJRFE" - + "3ivL8KAWc1cN0VUx9YigEO8m6Svmw7a2mgPrNh7A3UvUcCwrpixKjKHOprnz3DIG7tKsO5IwJgG07-Uz" - + "W6V0eyJ-SDuhenxgsn1sBQ1431DifCBOHWYhXCqPP4Jlbvvvd-1zNjfZeTx6DpkVSIX-RA8xnWs0LcSq" - + "4xgl6v29qCXNgPSy9ax0pxZzXdemws3ZR_IqOXp4bf8Oe0he9_mI7DJEMpIDzHPzRcljRTdvywyvCicf" - + "sDUnMX0z1q7-goYearYEAkz6Vb_ulC9Y8ICWri4ELruQlH1WM13Iibogjdj6uKmfbfkfdJ9AVQZmVv9B" - + "4CJbZIWlDc6LqQS4gxMtUbAvRLz-n-4j1u__4rMUYUJIbSL8bWjXYlCqtiT89QnR8Go-3fy0"; + + public static final String DONORS = "6qq90AmER5DS9tl8vfhbtlpPbKCCAM84o_E4uZ2mYAUx0V47kBTjx2k8Nq5mIRiNHY1PcfrHNOSGbmZ6" + + "UZUdwEgVdbcBbJybk-gCEFN2l32zqB1XCybzPh80tdwg32d1lpLJ_WZwmrDMI5HRTZHHjDaZL_zlEeNa" + + "eI8CGxCL7YMZ4Mf_89AnPgUQmzsFQjsrwk8kA7HReSPqYZY6gyBS4Xz5LlOApDboYPUh5efRQHnxGSMj" + + "cF0IAQwsiGGkEQY9IaqEPxWXzVKVzGRQRAwmKikzeBYs8KcjV__OEGvmVWw3IXY7MB21COSAX_a4FKMz" + + "4OEnYqGJfPuCOnCndpmnm8GNcjZ0FyeYfaTfPaz76yRXaL30vTTm0d5KLLHeTl0ne7YKMdIicAwBuqwp" + + "-lhGUqeQYuQRm8A31Mc2L01v4tJ2dn5hV5MvjztGm2lEpZhRPY6lyl3oyUP6tzwuir2-xnwUwUEweTgY" + + "bBcDxwszvoqWTolrMl5FEMAPQ-9skNegqFBh1V8Fe9VcHCNwcPU7XUOGzpRiYxZF-PsF8G9ZnMcmsBiO" + + "wZNfoIv_iuaipo0Bl8IVYutCn1Q-Sl4mw9TQyJoYyuMGPMNvkEXeMNjCj2PkrhrzikU8kPh_VpTzX9ca" + + "4tGoHMtgceXIPkrUjIU35C7JG6-6t0Ho1whJzIfE7nVvptf0z5P51gAqEUFzGd51RMWpn1nOwqA96y3y" + + "Af5E6AUJj4HQ0-XjkBA8j6NQy-xAsRvYpBrCSc6xQpHMn0TooBEQtJq56saObx9PEgBzW3s1Hx6pN7Ms" + + "m5e5EExflUlDLF-9WNgL9oKXhKUKnp7ygsR34gMoQ9kyMShVC_t6duUkBzZJeaDCAxqEMGog5ur8fNyP" + + "_Mv5wUyWPMDUya7Um5TqJ0DXolWKSBjvCgMABHYxThh3mXOWtERYYbK1SFT2TIujAxUmAMRTS_KnK2b-" + + "Z4zWgCmBpmhiEEy5EWCzIgoFvhtIvscvDmLR2oXJBGGBQQAShHGKvMkHZ5ZhqdFG1dZxou8BzDQUet6a" + + "G_5h8ReZRG2qPb6DqEUw0Pa8bN95l-PZOGJyxQ-ltODH1n__EePFnK6yf2G6f0BQqOtpe7wwferWlKMV" + + "Vz-sgu_Wpx_cqH2dQhltjmRHwo38Vu62S3fNp-0mAlDdu0FZT2KzeDJ1IgsyD7eQO4GGqhAUI_kSaHuP" + + "K-NsrI9th0yL_sqhnWdAUCFAYqM2eiMIitoxMYPL8FRrEnQd73B-JrHv9f9BLqv68XGxEyIPZVVHXk7c" + + "c-36JCSL0crVVxURrQaokv2Srt0WCW00"; @Override final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed) diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/error/PSystemError.java similarity index 62% rename from src/net/sourceforge/plantuml/PSystemError.java rename to src/net/sourceforge/plantuml/error/PSystemError.java index 9d338f7a9..93e6349f3 100644 --- a/src/net/sourceforge/plantuml/PSystemError.java +++ b/src/net/sourceforge/plantuml/error/PSystemError.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml; +package net.sourceforge.plantuml.error; import java.awt.Color; import java.awt.geom.Dimension2D; @@ -42,18 +42,26 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.BackSlash; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ErrorUml; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.FileImageData; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.api.ImageDataAbstract; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.asciiart.UmlCharArea; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; -import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.eggs.PSystemWelcome; import net.sourceforge.plantuml.flashcode.FlashCodeFactory; @@ -69,6 +77,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.InnerStrategy; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockRaw; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.VerticalAlignment; import net.sourceforge.plantuml.svek.TextBlockBackcolored; @@ -83,53 +92,109 @@ import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; import net.sourceforge.plantuml.version.LicenseInfo; import net.sourceforge.plantuml.version.PSystemVersion; -public class PSystemError extends AbstractPSystem { +public abstract class PSystemError extends AbstractPSystem { - private final LineLocation higherErrorPosition; - private final List printedErrors; - private final List debugLines = new ArrayList(); + protected List trace; + protected ErrorUml singleError; - public PSystemError(UmlSource source, ErrorUml singleError, List debugLines) { - this(source, Collections.singletonList(singleError), debugLines); + final protected StringLocated getLastLine() { + return trace.get(trace.size() - 1); } - private PSystemError(UmlSource source, List all, List debugLines) { - this.setSource(source); + final public LineLocation getLineLocation() { + return getLastLine().getLocation(); + } - final LineLocation execution = getHigherErrorPosition2(ErrorUmlType.EXECUTION_ERROR, all); - final LineLocation syntax = getHigherErrorPosition2(ErrorUmlType.SYNTAX_ERROR, all); + final public Collection getErrorsUml() { + return Collections.singleton(singleError); + } - if (execution == null && syntax == null) { - throw new IllegalStateException(); + final public String getWarningOrError() { + final StringBuilder sb = new StringBuilder(); + sb.append(getDescription()); + sb.append(BackSlash.CHAR_NEWLINE); + for (CharSequence t : getTitle().getDisplay()) { + sb.append(t); + sb.append(BackSlash.CHAR_NEWLINE); } + sb.append(BackSlash.CHAR_NEWLINE); + return sb.toString(); + } - if (execution != null && (syntax == null || execution.compareTo(syntax) >= 0)) { - higherErrorPosition = execution; - printedErrors = getErrorsAt2(execution, ErrorUmlType.EXECUTION_ERROR, all); + private TextBlockBackcolored getGraphicalFormatted() { + final FontConfiguration fc0 = GraphicStrings.sansSerif14(HtmlColorUtils.BLACK).bold(); + final FontConfiguration fc1 = GraphicStrings.sansSerif14(HtmlColorUtils.MY_GREEN).bold(); + final FontConfiguration fc2 = GraphicStrings.sansSerif14(HtmlColorUtils.RED).bold(); + + final List fullBody = getTextFullBody(); + final TextBlock result0 = TextBlockUtils.addBackcolor( + TextBlockUtils.withMargin(new TextBlockRaw(getTextFromStack(), fc0), 1, 1, 1, 4), + HtmlColorUtils.MY_GREEN); + final TextBlock result1 = new TextBlockRaw(allButLast(fullBody), fc1); + final TextBlock result2 = new TextBlockRaw(onlyLast(fullBody), fc1.wave(HtmlColorUtils.RED)); + final TextBlock result3 = new TextBlockRaw(getTextError(), fc2); + TextBlock result = result0; + result = TextBlockUtils.mergeTB(result, result1, HorizontalAlignment.LEFT); + result = TextBlockUtils.mergeTB(result, result2, HorizontalAlignment.LEFT); + result = TextBlockUtils.mergeTB(result, result3, HorizontalAlignment.LEFT); + result = TextBlockUtils.withMargin(result, 5, 5); + return TextBlockUtils.addBackcolor(result, HtmlColorUtils.BLACK); + } + + private List getPureAsciiFormatted() { + final List result = getTextFromStack(); + result.addAll(getTextFullBody()); + result.add("^^^^^"); + result.addAll(getTextError()); + return result; + } + + private List getTextFromStack() { + LineLocation lineLocation = getLineLocation(); + final List result = new ArrayList(); + if (lineLocation != null) { + append(result, lineLocation); + while (lineLocation.getParent() != null) { + lineLocation = lineLocation.getParent(); + append(result, lineLocation); + } + } + return result; + } + + private List getTextFullBody() { + final List result = new ArrayList(); + result.add(" "); + final int traceSize = trace.size(); + if (traceSize > 40) { + for (StringLocated s : trace.subList(0, 5)) { + addToResult(result, s); + } + result.add("..."); + final int skipped = traceSize - 5 - 20; + result.add("... ( skipping " + skipped + " lines )"); + result.add("..."); + for (StringLocated s : trace.subList(traceSize - 20, traceSize)) { + addToResult(result, s); + } } else { - // assert syntax.compareTo(execution) > 0; - higherErrorPosition = syntax; - printedErrors = getErrorsAt2(syntax, ErrorUmlType.SYNTAX_ERROR, all); + for (StringLocated s : trace) { + addToResult(result, s); + } } - - if (debugLines != null) { - this.debugLines.addAll(debugLines); - } - + return result; } - private String getSuggestColor(boolean useRed) { - if (useRed) { - return "black"; + private void addToResult(final List result, StringLocated s) { + String tmp = s.getString(); + if (tmp.length() > 120) { + tmp = tmp.substring(0, 120) + " ..."; } - return "white"; + result.add(tmp); } - private String getRed(boolean useRed) { - if (useRed) { - return "#CD0A0A"; - } - return "red"; + private List getTextError() { + return Arrays.asList(" " + singleError.getError()); } @Override @@ -138,13 +203,13 @@ public class PSystemError extends AbstractPSystem { if (fileFormat.getFileFormat() == FileFormat.ATXT || fileFormat.getFileFormat() == FileFormat.UTXT) { final UGraphicTxt ugt = new UGraphicTxt(); final UmlCharArea area = ugt.getCharArea(); - area.drawStringsLR(getTextStrings(), 0, 0); + area.drawStringsLR(getPureAsciiFormatted(), 0, 0); area.print(new PrintStream(os)); return new ImageDataSimple(1, 1); } - final boolean useRed = fileFormat.isUseRedForError(); - final TextBlockBackcolored result = GraphicStrings.createForError(getHtmlStrings(useRed), useRed); + // final boolean useRed = fileFormat.isUseRedForError(); + final TextBlockBackcolored result = getGraphicalFormatted(); TextBlock udrawable; final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), @@ -156,11 +221,11 @@ public class PSystemError extends AbstractPSystem { } final int min = (int) (System.currentTimeMillis() / 60000L) % 60; // udrawable = addMessageAdopt(udrawable); - if (min == 1 && LicenseInfo.retrieveNamedOrDistributorQuickIsValid() == false) { + if (min == 1 || min == 8) { udrawable = addMessagePatreon(udrawable); - } else if (min == 15 && LicenseInfo.retrieveNamedOrDistributorQuickIsValid() == false) { + } else if (min == 15) { udrawable = addMessageLiberapay(udrawable); - } else if (min == 30 && LicenseInfo.retrieveNamedOrDistributorQuickIsValid() == false) { + } else if (min == 30) { udrawable = addMessageDedication(udrawable); } else if (getSource().containsIgnoreCase("arecibo")) { udrawable = addMessageArecibo(udrawable); @@ -171,6 +236,31 @@ public class PSystemError extends AbstractPSystem { return imageData; } + private void append(List result, LineLocation lineLocation) { + if (lineLocation.getDescription() != null) { + result.add("[From " + lineLocation.getDescription() + " (line " + (lineLocation.getPosition() + 1) + ") ]"); + } + } + + // private String getRed(boolean useRed) { + // if (useRed) { + // return "#CD0A0A"; + // } + // return "red"; + // } + // + final public DiagramDescription getDescription() { + return new DiagramDescription("(Error)"); + } + + private List allButLast(List full) { + return full.subList(0, full.size() - 1); + } + + private List onlyLast(List full) { + return full.subList(full.size() - 1, full.size()); + } + private TextBlockBackcolored getWelcome() throws IOException { return new PSystemWelcome(GraphicPosition.BACKGROUND_CORNER_TOP_RIGHT).getGraphicStrings(); } @@ -181,6 +271,9 @@ public class PSystemError extends AbstractPSystem { } private TextBlock addMessageLiberapay(final TextBlock source) throws IOException { + if (LicenseInfo.retrieveNamedOrDistributorQuickIsValid()) { + return source; + } final TextBlock message = getMessageLiberapay(); TextBlock result = TextBlockUtils.mergeTB(message, source, HorizontalAlignment.LEFT); result = TextBlockUtils.mergeTB(result, message, HorizontalAlignment.LEFT); @@ -188,6 +281,9 @@ public class PSystemError extends AbstractPSystem { } private TextBlock addMessagePatreon(final TextBlock source) throws IOException { + if (LicenseInfo.retrieveNamedOrDistributorQuickIsValid()) { + return source; + } final TextBlock message = getMessagePatreon(); TextBlock result = TextBlockUtils.mergeTB(message, source, HorizontalAlignment.LEFT); result = TextBlockUtils.mergeTB(result, message, HorizontalAlignment.LEFT); @@ -195,12 +291,18 @@ public class PSystemError extends AbstractPSystem { } private TextBlock addMessageDedication(final TextBlock source) throws IOException { + if (LicenseInfo.retrieveNamedOrDistributorQuickIsValid()) { + return source; + } final TextBlock message = getMessageDedication(); TextBlock result = TextBlockUtils.mergeTB(message, source, HorizontalAlignment.LEFT); return result; } private TextBlock addMessageAdopt(final TextBlock source) throws IOException { + if (LicenseInfo.retrieveNamedOrDistributorQuickIsValid()) { + return source; + } final TextBlock message = getMessageAdopt(); TextBlock result = TextBlockUtils.mergeTB(message, source, HorizontalAlignment.LEFT); return result; @@ -341,6 +443,10 @@ public class PSystemError extends AbstractPSystem { } + public int size() { + return trace.size(); + } + private BufferedImage smaller(BufferedImage im) { if (im == null) { return null; @@ -349,241 +455,4 @@ public class PSystemError extends AbstractPSystem { return im.getSubimage(nb, nb, im.getWidth() - 2 * nb, im.getHeight() - 2 * nb); } - private List getTextStrings() { - final List result = new ArrayList(getStack()); - if (result.size() > 0) { - result.add(" "); - } - - for (String s : getPartialCode()) { - result.add(s); - } - final String errorLine = getSource().getLine(higherErrorPosition); - final String err = StringUtils.hideComparatorCharacters(errorLine); - if (StringUtils.isNotEmpty(err)) { - result.add(err); - } - final StringBuilder underscore = new StringBuilder(); - for (int i = 0; i < errorLine.length(); i++) { - underscore.append("^"); - } - result.add(underscore.toString()); - final Collection textErrors = new LinkedHashSet(); - for (ErrorUml er : printedErrors) { - textErrors.add(er.getError()); - } - for (String er : textErrors) { - result.add(" " + er); - } - boolean first = true; - for (String s : getSuggest()) { - if (first) { - result.add(" " + s); - } else { - result.add(s); - } - first = false; - } - result.addAll(this.debugLines); - - return result; - } - - private List getStack() { - LineLocation lineLocation = getLineLocation(); - final List result = new ArrayList(); - if (lineLocation != null) { - append(result, lineLocation); - while (lineLocation.getParent() != null) { - lineLocation = lineLocation.getParent(); - append(result, lineLocation); - } - } - return result; - } - - public LineLocation getLineLocation() { - for (ErrorUml err : printedErrors) { - if (err.getLineLocation() != null) { - return err.getLineLocation(); - } - } - return null; - } - - private void append(List result, LineLocation lineLocation) { - if (lineLocation.getDescription() != null) { - result.add("[From " + lineLocation.getDescription() + " (line " + (lineLocation.getPosition() + 1) + ") ]"); - } - } - - private List getPartialCode() { - List result = new ArrayList(); - for (Iterator it = getSource().iterator2(); it.hasNext();) { - final StringLocated s = it.next(); - final String tmp = s.getString(); - result.add(tmp); - final LineLocation location = s.getLocation(); - if (location.getDescription().equals(higherErrorPosition.getDescription()) - && location.compareTo(higherErrorPosition) >= 0) { - break; - } - } - final int limit = 5; - if (result.size() > limit) { - final int skip = result.size() - limit + 1; - final String skipMessage; - if (skip == 1) { - skipMessage = "... (skipping 1 line) ..."; - } else { - skipMessage = "... (skipping " + skip + " lines) ..."; - } - result = new ArrayList(result.subList(skip, result.size())); - result.add(0, skipMessage); - } - return result; - - } - - private List getHtmlStrings(boolean useRed) { - final List htmlStrings = new ArrayList(getStack()); - if (htmlStrings.size() > 0) { - htmlStrings.add("----"); - } - - final List partialCode = getPartialCode(); - for (String s : partialCode) { - htmlStrings.add(StringUtils.hideComparatorCharacters(s)); - } - if (partialCode.size() > 0) { - final int idx = htmlStrings.size() - 1; - final String last = htmlStrings.get(idx); - htmlStrings.set(idx, "" + last + ""); - } - - final Collection textErrors = new LinkedHashSet(); - for (ErrorUml er : printedErrors) { - textErrors.add(er.getError()); - } - for (String er : textErrors) { - htmlStrings.add(" " + er + ""); - } - boolean first = true; - for (String s : getSuggest()) { - if (first) { - htmlStrings.add(" " + s + ""); - } else { - htmlStrings.add("" + StringUtils.hideComparatorCharacters(s) - + ""); - } - first = false; - } - htmlStrings.addAll(this.debugLines); - - return htmlStrings; - } - - private List getSuggest() { - boolean suggested = false; - for (ErrorUml er : printedErrors) { - if (er.hasSuggest()) { - suggested = true; - } - } - if (suggested == false) { - return Collections.emptyList(); - } - final List result = new ArrayList(); - result.add("Did you mean:"); - for (ErrorUml er : printedErrors) { - if (er.hasSuggest()) { - result.add(er.getSuggest().getSuggestedLine()); - } - } - return Collections.unmodifiableList(result); - - } - - private Collection getErrors(ErrorUmlType type, List all) { - final Collection result = new LinkedHashSet(); - for (ErrorUml error : all) { - if (error.getType() == type) { - result.add(error); - } - } - return result; - } - - private LineLocation getHigherErrorPosition2(ErrorUmlType type, List all) { - LineLocation max = null; - for (ErrorUml error : getErrors(type, all)) { - if (max == null || error.getLineLocation().compareTo(max) > 0) { - max = error.getLineLocation(); - } - } - return max; - } - - private List getErrorsAt2(LineLocation position, ErrorUmlType type, List all) { - final List result = new ArrayList(); - for (ErrorUml error : getErrors(type, all)) { - if (error.getLineLocation().compareTo(position) == 0 && StringUtils.isNotEmpty(error.getError())) { - result.add(error); - } - } - return result; - } - - public DiagramDescription getDescription() { - return new DiagramDescription("(Error)"); - } - - public final LineLocation getHigherErrorPosition2() { - return higherErrorPosition; - } - - public final Collection getErrorsUml() { - return Collections.unmodifiableCollection(printedErrors); - } - - @Override - public String getWarningOrError() { - final StringBuilder sb = new StringBuilder(); - sb.append(getDescription()); - sb.append(BackSlash.CHAR_NEWLINE); - for (CharSequence t : getTitle().getDisplay()) { - sb.append(t); - sb.append(BackSlash.CHAR_NEWLINE); - } - sb.append(BackSlash.CHAR_NEWLINE); - for (String s : getSuggest()) { - sb.append(s); - sb.append(BackSlash.CHAR_NEWLINE); - } - return sb.toString(); - } - - public static PSystemError merge(Collection ps) { - UmlSource source = null; - final List errors = new ArrayList(); - final List debugs = new ArrayList(); - for (PSystemError system : ps) { - if (system == null) { - continue; - } - if (system.getSource() != null && source == null) { - source = system.getSource(); - } - errors.addAll(system.getErrorsUml()); - debugs.addAll(system.debugLines); - if (system.debugLines.size() > 0) { - debugs.add("-"); - } - } - if (source == null) { - throw new IllegalStateException(); - } - return new PSystemError(source, errors, debugs); - } - } diff --git a/src/net/sourceforge/plantuml/error/PSystemErrorPreprocessor.java b/src/net/sourceforge/plantuml/error/PSystemErrorPreprocessor.java new file mode 100644 index 000000000..bd2696ab1 --- /dev/null +++ b/src/net/sourceforge/plantuml/error/PSystemErrorPreprocessor.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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.error; + +import java.util.List; + +import net.sourceforge.plantuml.ErrorUml; +import net.sourceforge.plantuml.ErrorUmlType; +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.core.DiagramType; +import net.sourceforge.plantuml.core.UmlSource; + +public class PSystemErrorPreprocessor extends PSystemError { + + public PSystemErrorPreprocessor(List input, List trace) { + final DiagramType type = DiagramType.getTypeFromArobaseStart(input.get(0).getString()); + this.setSource(new UmlSource(input, type == DiagramType.UML)); + this.trace = trace; + this.singleError = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, getLastLine().getPreprocessorError(), getLastLine() + .getLocation()); + + } + + + + +} diff --git a/src/net/sourceforge/plantuml/error/PSystemErrorUtils.java b/src/net/sourceforge/plantuml/error/PSystemErrorUtils.java new file mode 100644 index 000000000..d68f56f8e --- /dev/null +++ b/src/net/sourceforge/plantuml/error/PSystemErrorUtils.java @@ -0,0 +1,106 @@ +/* ======================================================================== + * 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.error; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.ErrorUml; +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.core.UmlSource; + +public class PSystemErrorUtils { + + // public static AbstractPSystemError buildV1(UmlSource source, ErrorUml singleError, List debugLines) { + // return new PSystemErrorV1(source, singleError, debugLines); + // } + + public static PSystemError buildV2(UmlSource source, ErrorUml singleError, List debugLines, + List list) { + // return new PSystemErrorV1(source, singleError, debugLines); + return new PSystemErrorV2(source, list, singleError); + } + + public static PSystemError merge(Collection ps) { + UmlSource source = null; + final List errors = new ArrayList(); + // final List debugs = new ArrayList(); + final List errorsV2 = new ArrayList(); + for (PSystemError system : ps) { + if (system == null) { + continue; + } + if (system.getSource() != null && source == null) { + source = system.getSource(); + } + errors.addAll(system.getErrorsUml()); + // if (system instanceof PSystemErrorV1) { + // debugs.addAll(((PSystemErrorV1) system).debugLines); + // if (((PSystemErrorV1) system).debugLines.size() > 0) { + // debugs.add("-"); + // } + // } + if (system instanceof PSystemErrorV2) { + errorsV2.add((PSystemErrorV2) system); + } + } + if (source == null) { + throw new IllegalStateException(); + } + if (errorsV2.size() > 0) { + return mergeV2(errorsV2); + } + throw new IllegalStateException(); + // return new PSystemErrorV1(source, errors, debugs); + } + + private static PSystemErrorV2 mergeV2(List errorsV2) { + PSystemErrorV2 result = null; + for (PSystemErrorV2 err : errorsV2) { + if (result == null || result.size() < err.size()) { + result = err; + } + } + return result; + } + + public static boolean isDiagramError(Class type) { + return PSystemError.class.isAssignableFrom(type); + // return type == PSystemErrorV1.class; + } + +} diff --git a/src/net/sourceforge/plantuml/suggest/SuggestEngineStatus.java b/src/net/sourceforge/plantuml/error/PSystemErrorV2.java similarity index 74% rename from src/net/sourceforge/plantuml/suggest/SuggestEngineStatus.java rename to src/net/sourceforge/plantuml/error/PSystemErrorV2.java index afef8ac83..6c3108d68 100644 --- a/src/net/sourceforge/plantuml/suggest/SuggestEngineStatus.java +++ b/src/net/sourceforge/plantuml/error/PSystemErrorV2.java @@ -31,11 +31,22 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.error; -public enum SuggestEngineStatus { - SYNTAX_OK, CANNOT_CORRECT, ONE_SUGGESTION +import java.util.List; + +import net.sourceforge.plantuml.ErrorUml; +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.core.UmlSource; + +public class PSystemErrorV2 extends PSystemError { + + public PSystemErrorV2(UmlSource source, List trace, ErrorUml singleError) { + this.setSource(source); + this.trace = trace; + this.singleError = singleError; + + } } diff --git a/src/net/sourceforge/plantuml/fun/IconLoader.java b/src/net/sourceforge/plantuml/fun/IconLoader.java index 7e7b35d17..4e3b7b04a 100644 --- a/src/net/sourceforge/plantuml/fun/IconLoader.java +++ b/src/net/sourceforge/plantuml/fun/IconLoader.java @@ -44,12 +44,12 @@ import javax.imageio.ImageIO; public class IconLoader { - private static final int NUMBER_OF_ICONS = 27; + private static final int NUMBER_OF_ICONS = 29; private final static Map all = new ConcurrentHashMap(); public static BufferedImage getRandom() { - // return addTransparent(getIcon("sprite026.png")); + // return addTransparent(getIcon("sprite028.png")); return addTransparent(getIcon(getSomeQuote())); } diff --git a/src/net/sourceforge/plantuml/fun/sprite021.png b/src/net/sourceforge/plantuml/fun/sprite021.png index efc0b8665..ef4522ed4 100644 Binary files a/src/net/sourceforge/plantuml/fun/sprite021.png and b/src/net/sourceforge/plantuml/fun/sprite021.png differ diff --git a/src/net/sourceforge/plantuml/fun/sprite027.png b/src/net/sourceforge/plantuml/fun/sprite027.png new file mode 100644 index 000000000..f1d203684 Binary files /dev/null and b/src/net/sourceforge/plantuml/fun/sprite027.png differ diff --git a/src/net/sourceforge/plantuml/fun/sprite028.png b/src/net/sourceforge/plantuml/fun/sprite028.png new file mode 100644 index 000000000..e86483d8a Binary files /dev/null and b/src/net/sourceforge/plantuml/fun/sprite028.png differ diff --git a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java index 14603f570..a44c03963 100644 --- a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java +++ b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java @@ -222,6 +222,10 @@ public class FontConfiguration { return add(FontStyle.UNDERLINE); } + public FontConfiguration wave(HtmlColor color) { + return add(FontStyle.WAVE).changeExtendedColor(color); + } + public FontConfiguration hyperlink() { if (useUnderlineForHyperlink) { return add(FontStyle.UNDERLINE).withHyperlink(); diff --git a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java index 1c63aac82..cd748b67a 100644 --- a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java +++ b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java @@ -41,6 +41,7 @@ import java.util.List; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.svek.IEntityImage; import net.sourceforge.plantuml.svek.Margins; @@ -58,13 +59,9 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage { private final HtmlColor background; - private final UFont font; + private final static HtmlColor hyperlinkColor = HtmlColorUtils.BLUE; - private final HtmlColor maincolor; - - private final HtmlColor hyperlinkColor = HtmlColorUtils.BLUE; - - private final boolean useUnderlineForHyperlink = true; + private final static boolean useUnderlineForHyperlink = true; private final List strings; @@ -72,63 +69,87 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage { private final GraphicPosition position; + private final FontConfiguration fontConfiguration; + public static IEntityImage createForError(List strings, boolean useRed) { + return new GraphicStrings(strings, sansSerif14(getForeColor(useRed)).bold(), getBackColor(useRed), null, null, + CreoleMode.NO_CREOLE); + } + + private static HtmlColor getForeColor(boolean useRed) { if (useRed) { - return new GraphicStrings(strings, UFont.sansSerif(14).bold(), HtmlColorUtils.BLACK, - HtmlColorUtils.RED_LIGHT, null, null); + return HtmlColorUtils.BLACK; } - return new GraphicStrings(strings, UFont.sansSerif(14).bold(), HtmlColorSet.getInstance().getColorIfValid( - "#33FF02"), HtmlColorUtils.BLACK, null, null); + return HtmlColorUtils.MY_GREEN; + } + + private static HtmlColor getBackColor(boolean useRed) { + if (useRed) { + return HtmlColorUtils.RED_LIGHT; + } + return HtmlColorUtils.BLACK; } public static TextBlockBackcolored createGreenOnBlackMonospaced(List strings) { - return new GraphicStrings(strings, monospaced14(), HtmlColorUtils.GREEN, HtmlColorUtils.BLACK, null, null); + return new GraphicStrings(strings, monospaced14(HtmlColorUtils.GREEN), HtmlColorUtils.BLACK, null, null, + CreoleMode.SIMPLE_LINE); } public static TextBlockBackcolored createBlackOnWhite(List strings) { - return new GraphicStrings(strings, sansSerif12(), HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, null, null); + return new GraphicStrings(strings, sansSerif12(HtmlColorUtils.BLACK), HtmlColorUtils.WHITE, null, null, + CreoleMode.FULL); } public static TextBlockBackcolored createBlackOnWhiteMonospaced(List strings) { - return new GraphicStrings(strings, monospaced14(), HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, null, null); + return new GraphicStrings(strings, monospaced14(HtmlColorUtils.BLACK), HtmlColorUtils.WHITE, null, null, + CreoleMode.FULL); } public static TextBlockBackcolored createBlackOnWhite(List strings, BufferedImage image, GraphicPosition position) { - return new GraphicStrings(strings, sansSerif12(), HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, image, position); + return new GraphicStrings(strings, sansSerif12(HtmlColorUtils.BLACK), HtmlColorUtils.WHITE, image, position, + CreoleMode.FULL); } - private static UFont sansSerif12() { - return UFont.sansSerif(12); + private static FontConfiguration sansSerif12(HtmlColor color) { + return new FontConfiguration(UFont.sansSerif(12), color, hyperlinkColor, useUnderlineForHyperlink); } - private static UFont monospaced14() { - return UFont.monospaced(14); + public static FontConfiguration sansSerif14(HtmlColor color) { + return new FontConfiguration(UFont.sansSerif(14), color, hyperlinkColor, useUnderlineForHyperlink); } - private GraphicStrings(List strings, UFont font, HtmlColor maincolor, HtmlColor background, - BufferedImage image, GraphicPosition position) { + private static FontConfiguration monospaced14(HtmlColor color) { + return new FontConfiguration(UFont.monospaced(14), color, hyperlinkColor, useUnderlineForHyperlink); + } + + private final CreoleMode mode; + + private GraphicStrings(List strings, FontConfiguration fontConfiguration, HtmlColor background, + BufferedImage image, GraphicPosition position, CreoleMode mode) { this.strings = strings; - this.font = font; - this.maincolor = maincolor; this.background = background; this.image = image; this.position = position; + this.mode = mode; + this.fontConfiguration = fontConfiguration; + } private TextBlock getTextBlock() { - TextBlock result = null; - result = Display.create(strings).create( - new FontConfiguration(font, maincolor, hyperlinkColor, useUnderlineForHyperlink), - HorizontalAlignment.LEFT, new SpriteContainerEmpty()); - // result = DateEventUtils.addEvent(result, green); - return result; + final Display display = Display.create(strings); + if (mode == CreoleMode.NO_CREOLE) { + return new TextBlockRaw(strings, fontConfiguration); + + } else { + return display.create(fontConfiguration, HorizontalAlignment.LEFT, new SpriteContainerEmpty(), mode); + } } public void drawU(UGraphic ug) { ug = ug.apply(new UTranslate(margin, margin)); final Dimension2D size = calculateDimensionInternal(ug.getStringBounder()); - getTextBlock().drawU(ug.apply(new UChangeColor(maincolor))); + getTextBlock().drawU(ug.apply(new UChangeColor(fontConfiguration.getColor()))); if (image != null) { if (position == GraphicPosition.BOTTOM) { @@ -176,10 +197,9 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage { public boolean isHidden() { return false; } - + public double getOverscanX(StringBounder stringBounder) { return 0; } - } diff --git a/src/net/sourceforge/plantuml/graphic/HtmlColorUtils.java b/src/net/sourceforge/plantuml/graphic/HtmlColorUtils.java index 43ace0083..02c568845 100644 --- a/src/net/sourceforge/plantuml/graphic/HtmlColorUtils.java +++ b/src/net/sourceforge/plantuml/graphic/HtmlColorUtils.java @@ -48,6 +48,7 @@ public class HtmlColorUtils { public static final HtmlColor LIGHT_GRAY; public static final HtmlColor MY_YELLOW; public static final HtmlColor MY_RED; + public static final HtmlColor MY_GREEN; public static final HtmlColor COL_C82930; public static final HtmlColor COL_F24D5C; @@ -86,6 +87,7 @@ public class HtmlColorUtils { LIGHT_GRAY = set.getColorIfValid("#C0C0C0"); MY_YELLOW = set.getColorIfValid("#FEFECE"); MY_RED = set.getColorIfValid("#A80036"); + MY_GREEN = set.getColorIfValid("#33FF02"); COL_C82930 = set.getColorIfValid("#C82930"); COL_F24D5C = set.getColorIfValid("#F24D5C"); diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index ec8fec644..8aa6c9960 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -304,7 +304,16 @@ public class QuoteUtils { "Dhnaq ibhf rgrf rzorgrf, rzoebhvyyrm gbhg", "Gurer nva'g ab phevat jung'f jebat jvgu gung guvat", "Vs lbh cevpx hf, qb jr abg oyrrq?", "V qvq lbhe wbo bapr - V jnf tbbq ng vg.", "Vyf cbheenvrag snver har fryrpgvba nh fgnaqneq...", "Gung'f ab jnl gb gerng n sevraq.", - "Ubjrire ornhgvshy gur fgengrtl, lbh fubhyq bppnfvbanyyl ybbx ng gur erfhygf"); + "Ubjrire ornhgvshy gur fgengrtl, lbh fubhyq bppnfvbanyyl ybbx ng gur erfhygf", + "Qba'g svk vg vs vg'f abg oebxra", + "Fhqqrayl V'z gnxvat fhttrfgvbaf sebz fbzr fgebat-nez zna jvgu na VD bs zvahf 50.", + "Fur ehvaf rirelguvat fur'f va. Fur ehvaf guvatf fur'f abg rira va.", + "Byvir, V guvax lbh fubhyq xabj guvf: lbh'er n ubeevoyr npgerff.", + "Lbh'er yngr! Qb lbh unir ab pbaprcg bs gvzr ?", + "P'zba zna, yrg'f qb fbzrguvat gung ernyyl pbbxf.", + "Nh sbaq, znvagranag, yrf qvcybzngrf ceraqenvrag cyhgbg yr cnf fhe yrf ubzzrf q'npgvba.", + "Whfg zragnyyl gubhtu... ner lbh bxnl ?", "Jr xabj fur'f bxnl orpnhfr fur'f oybaq", + "Gh oyhssrf Znegbav"); private QuoteUtils() { } diff --git a/src/net/sourceforge/plantuml/graphic/SingleLine.java b/src/net/sourceforge/plantuml/graphic/SingleLine.java index 60a2ea3cd..3c8400a0b 100644 --- a/src/net/sourceforge/plantuml/graphic/SingleLine.java +++ b/src/net/sourceforge/plantuml/graphic/SingleLine.java @@ -51,7 +51,24 @@ class SingleLine extends AbstractTextBlock implements Line { private final List blocs = new ArrayList(); private final HorizontalAlignment horizontalAlignment; - public SingleLine(String text, FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, + public static SingleLine withSomeHtmlTag(String text, FontConfiguration fontConfiguration, + HorizontalAlignment horizontalAlignment, SpriteContainer spriteContainer) { + return new SingleLine(text, fontConfiguration, horizontalAlignment, spriteContainer); + } + + public static SingleLine rawText(String text, FontConfiguration fontConfiguration) { + return new SingleLine(text, fontConfiguration); + } + + private SingleLine(String text, FontConfiguration fontConfiguration) { + if (text.length() == 0) { + text = " "; + } + this.horizontalAlignment = HorizontalAlignment.LEFT; + this.blocs.add(new TileText(text, fontConfiguration, null)); + } + + private SingleLine(String text, FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, SpriteContainer spriteContainer) { if (text.length() == 0) { text = " "; @@ -139,4 +156,5 @@ class SingleLine extends AbstractTextBlock implements Line { public HorizontalAlignment getHorizontalAlignment() { return horizontalAlignment; } + } diff --git a/src/net/sourceforge/plantuml/graphic/SkinParameter.java b/src/net/sourceforge/plantuml/graphic/SkinParameter.java index d27491d01..7667d43d7 100644 --- a/src/net/sourceforge/plantuml/graphic/SkinParameter.java +++ b/src/net/sourceforge/plantuml/graphic/SkinParameter.java @@ -97,6 +97,10 @@ public class SkinParameter { ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE, LineParam.rectangleBorder, CornerParam.rectangle); + public static final SkinParameter ARCHIMATE = new SkinParameter("ARCHIMATE", ColorParam.archimateBackground, + ColorParam.archimateBorder, FontParam.ARCHIMATE, FontParam.ARCHIMATE_STEREOTYPE, LineParam.archimateBorder, + CornerParam.archimate); + public static final SkinParameter COLLECTIONS = new SkinParameter("COLLECTIONS", ColorParam.collectionsBackground, ColorParam.collectionsBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE); diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockRaw.java b/src/net/sourceforge/plantuml/graphic/TextBlockRaw.java new file mode 100644 index 000000000..af94867cf --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlockRaw.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * 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.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class TextBlockRaw extends AbstractTextBlock implements TextBlock { + + private List lines2; + + private final List strings; + private final FontConfiguration fontConfiguration; + + public TextBlockRaw(List strings, FontConfiguration fontConfiguration) { + this.strings = strings; + this.fontConfiguration = fontConfiguration; + } + + private List getLines(StringBounder stringBounder) { + if (lines2 == null) { + if (stringBounder == null) { + throw new IllegalStateException(); + } + this.lines2 = new ArrayList(); + for (String s : strings) { + lines2.add(SingleLine.rawText(s, fontConfiguration)); + } + } + return lines2; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return getTextDimension(stringBounder); + } + + protected final Dimension2D getTextDimension(StringBounder stringBounder) { + double width = 0; + double height = 0; + for (Line line : getLines(stringBounder)) { + final Dimension2D size2D = line.calculateDimension(stringBounder); + height += size2D.getHeight(); + width = Math.max(width, size2D.getWidth()); + } + return new Dimension2DDouble(width, height); + } + + public void drawU(UGraphic ug) { + double y = 0; + + for (Line line : getLines(ug.getStringBounder())) { + line.drawU(ug.apply(new UTranslate(0, y))); + y += line.calculateDimension(ug.getStringBounder()).getHeight(); + } + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java b/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java index 16e2d4c1e..abf993350 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java @@ -145,15 +145,15 @@ public class TextBlockSimple extends AbstractTextBlock implements TextBlock { if (s.length() == 0 || MyPattern.mtches(s, "^[%s]*$ ")) { return; } - lines2.add(new SingleLine(s, fontConfiguration, horizontalAlignment, spriteContainer)); + lines2.add(SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer)); } private void addSingleLine(String s) { - lines2.add(new SingleLine(s, fontConfiguration, horizontalAlignment, spriteContainer)); + lines2.add(SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer)); } private double getTextWidth(StringBounder stringBounder, String s) { - final Line line = new SingleLine(s, fontConfiguration, horizontalAlignment, spriteContainer); + final Line line = SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer); return line.calculateDimension(stringBounder).getWidth(); } @@ -162,7 +162,7 @@ public class TextBlockSimple extends AbstractTextBlock implements TextBlock { assert s.getLabel(Guillemet.DOUBLE_COMPARATOR) != null; final List result = new ArrayList(); for (String st : s.getLabels(spriteContainer.guillemet())) { - result.add(new SingleLine(st, fontConfiguration, horizontalAlignment, spriteContainer)); + result.add(SingleLine.withSomeHtmlTag(st, fontConfiguration, horizontalAlignment, spriteContainer)); } return Collections.unmodifiableList(result); } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java index 2c3156914..b05ae4bd5 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java @@ -124,6 +124,11 @@ public class TextBlockUtils { return new TextBlockVertical2(b1, b2, horizontalAlignment); } + // public static TextBlockBackcolored mergeColoredTB(TextBlockBackcolored b1, TextBlockBackcolored b2, + // HorizontalAlignment horizontalAlignment) { + // return addBackcolor(mergeTB(b1, b2, horizontalAlignment), b1.getBackcolor()); + // } + public static MinMax getMinMax(TextBlock tb, StringBounder stringBounder) { final LimitFinder limitFinder = new LimitFinder(stringBounder, false); tb.drawU(limitFinder); diff --git a/src/net/sourceforge/plantuml/graphic/USymbol.java b/src/net/sourceforge/plantuml/graphic/USymbol.java index 60daad2a3..a82290830 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbol.java +++ b/src/net/sourceforge/plantuml/graphic/USymbol.java @@ -58,14 +58,16 @@ public abstract class USymbol { public final static USymbol ARTIFACT = record("ARTIFACT", SkinParameter.ARTIFACT, new USymbolArtifact()); public final static USymbol PACKAGE = record("PACKAGE", SkinParameter.PACKAGE, new USymbolFolder( SkinParameter.PACKAGE, true)); - public final static USymbol FOLDER = record("FOLDER", SkinParameter.FOLDER, new USymbolFolder(SkinParameter.FOLDER, false)); + public final static USymbol FOLDER = record("FOLDER", SkinParameter.FOLDER, new USymbolFolder(SkinParameter.FOLDER, + false)); public final static USymbol FILE = record("FILE", SkinParameter.FILE, new USymbolFile()); public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE, new USymbolRect( - SkinParameter.RECTANGLE, HorizontalAlignment.CENTER)); + SkinParameter.RECTANGLE)); + public final static USymbol ARCHIMATE = record("ARCHIMATE", SkinParameter.ARCHIMATE, new USymbolRect( + SkinParameter.ARCHIMATE)); public final static USymbol COLLECTIONS = record("COLLECTIONS", SkinParameter.COLLECTIONS, new USymbolCollections( - SkinParameter.RECTANGLE, HorizontalAlignment.CENTER)); - public final static USymbol AGENT = record("AGENT", SkinParameter.AGENT, new USymbolRect(SkinParameter.AGENT, - HorizontalAlignment.CENTER)); + SkinParameter.RECTANGLE)); + public final static USymbol AGENT = record("AGENT", SkinParameter.AGENT, new USymbolRect(SkinParameter.AGENT)); public final static USymbol ACTOR = record("ACTOR", SkinParameter.ACTOR, new USymbolActor()); public final static USymbol USECASE = null; public final static USymbol COMPONENT1 = record("COMPONENT1", SkinParameter.COMPONENT1, new USymbolComponent1()); @@ -81,9 +83,9 @@ public abstract class USymbol { abstract public SkinParameter getSkinParameter(); - public USymbol withStereoAlignment(HorizontalAlignment alignment) { - return this; - } + // public USymbol withStereoAlignment(HorizontalAlignment alignment) { + // return this; + // } public FontParam getFontParam() { return getSkinParameter().getFontParam(); @@ -124,10 +126,11 @@ public abstract class USymbol { return symbol; } - public abstract TextBlock asSmall(TextBlock name, TextBlock label, TextBlock stereotype, SymbolContext symbolContext); + public abstract TextBlock asSmall(TextBlock name, TextBlock label, TextBlock stereotype, + SymbolContext symbolContext, HorizontalAlignment stereoAlignment); public abstract TextBlock asBig(TextBlock label, HorizontalAlignment labelAlignment, TextBlock stereotype, - double width, double height, SymbolContext symbolContext); + double width, double height, SymbolContext symbolContext, HorizontalAlignment stereoAlignment); static class Margin { private final double x1; diff --git a/src/net/sourceforge/plantuml/graphic/USymbolArtifact.java b/src/net/sourceforge/plantuml/graphic/USymbolArtifact.java index 5e40fd132..740a23256 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolArtifact.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolArtifact.java @@ -95,7 +95,7 @@ class USymbolArtifact extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -119,7 +119,7 @@ class USymbolArtifact extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolCard.java b/src/net/sourceforge/plantuml/graphic/USymbolCard.java index d701b1237..660baa97d 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolCard.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolCard.java @@ -73,7 +73,7 @@ class USymbolCard extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -96,7 +96,7 @@ class USymbolCard extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolCloud.java b/src/net/sourceforge/plantuml/graphic/USymbolCloud.java index 670e49794..62396fcf5 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolCloud.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolCloud.java @@ -216,7 +216,7 @@ class USymbolCloud extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -239,7 +239,7 @@ class USymbolCloud extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolCollections.java b/src/net/sourceforge/plantuml/graphic/USymbolCollections.java index 04ca4a540..107b12cb9 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolCollections.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolCollections.java @@ -47,17 +47,17 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class USymbolCollections extends USymbol { private final SkinParameter skinParameter; - private final HorizontalAlignment stereotypeAlignement; + // private final HorizontalAlignment stereotypeAlignement; - public USymbolCollections(SkinParameter skinParameter, HorizontalAlignment stereotypeAlignement) { + public USymbolCollections(SkinParameter skinParameter) { this.skinParameter = skinParameter; - this.stereotypeAlignement = stereotypeAlignement; + // this.stereotypeAlignement = stereotypeAlignement; } - @Override - public USymbol withStereoAlignment(HorizontalAlignment alignment) { - return new USymbolCollections(skinParameter, alignment); - } +// @Override +// public USymbol withStereoAlignment(HorizontalAlignment alignment) { +// return new USymbolCollections(skinParameter, alignment); +// } @Override public SkinParameter getSkinParameter() { @@ -85,7 +85,7 @@ class USymbolCollections extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -95,7 +95,7 @@ class USymbolCollections extends USymbol { drawCollections(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(), symbolContext.getRoundCorner()); final Margin margin = getMargin(); - final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereotypeAlignement); + final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment); tb.drawU(ug.apply(new UTranslate(margin.getX1() - getDeltaCollection() / 2, margin.getY1() - getDeltaCollection() / 2))); } @@ -110,7 +110,7 @@ class USymbolCollections extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { final Dimension2D dim = calculateDimension(ug.getStringBounder()); @@ -120,7 +120,7 @@ class USymbolCollections extends USymbol { final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder()); final double posStereoX; final double posStereoY; - if (stereotypeAlignement == HorizontalAlignment.RIGHT) { + if (stereoAlignment == HorizontalAlignment.RIGHT) { posStereoX = width - dimStereo.getWidth() - getMargin().getX1() / 2; posStereoY = getMargin().getY1() / 2; } else { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolComponent1.java b/src/net/sourceforge/plantuml/graphic/USymbolComponent1.java index 3860988a4..ff769dd5b 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolComponent1.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolComponent1.java @@ -75,7 +75,7 @@ class USymbolComponent1 extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -100,7 +100,7 @@ class USymbolComponent1 extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java b/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java index d4fdf1db6..f38dced23 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolComponent2.java @@ -78,7 +78,7 @@ class USymbolComponent2 extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -104,7 +104,7 @@ class USymbolComponent2 extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolDatabase.java b/src/net/sourceforge/plantuml/graphic/USymbolDatabase.java index 812bcc744..1a8b8a601 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolDatabase.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolDatabase.java @@ -114,7 +114,7 @@ class USymbolDatabase extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -137,7 +137,7 @@ class USymbolDatabase extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolFile.java b/src/net/sourceforge/plantuml/graphic/USymbolFile.java index e7980359d..42db16d0b 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolFile.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolFile.java @@ -105,7 +105,7 @@ class USymbolFile extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -129,7 +129,7 @@ class USymbolFile extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolFolder.java b/src/net/sourceforge/plantuml/graphic/USymbolFolder.java index b20be9f03..ca55ebe8d 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolFolder.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolFolder.java @@ -134,7 +134,7 @@ public class USymbolFolder extends USymbol { @Override public TextBlock asSmall(final TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { if (name == null) { throw new IllegalArgumentException(); } @@ -167,7 +167,7 @@ public class USymbolFolder extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolFrame.java b/src/net/sourceforge/plantuml/graphic/USymbolFrame.java index 71142b8d7..adb26d7e2 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolFrame.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolFrame.java @@ -98,7 +98,7 @@ class USymbolFrame extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -122,7 +122,7 @@ class USymbolFrame extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolNode.java b/src/net/sourceforge/plantuml/graphic/USymbolNode.java index b03d606dd..ac04800e0 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolNode.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolNode.java @@ -48,11 +48,22 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class USymbolNode extends USymbol { + // private final HorizontalAlignment stereotypeAlignement; + @Override public SkinParameter getSkinParameter() { return SkinParameter.NODE; } +// public USymbolNode(HorizontalAlignment stereotypeAlignement) { +// this.stereotypeAlignement = stereotypeAlignement; +// } +// +// @Override +// public USymbol withStereoAlignment(HorizontalAlignment alignment) { +// return new USymbolNode(alignment); +// } + private void drawNode(UGraphic ug, double width, double height, boolean shadowing) { final UPolygon shape = new UPolygon(); shape.addPoint(0, 10); @@ -111,7 +122,7 @@ class USymbolNode extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -119,7 +130,7 @@ class USymbolNode extends USymbol { ug = symbolContext.apply(ug); drawNode(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing()); final Margin margin = getMargin(); - final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, HorizontalAlignment.CENTER); + final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment); final UGraphic ug2 = new MyUGraphicNode(ug, dim.getWidth()); tb.drawU(ug2.apply(new UTranslate(margin.getX1(), margin.getY1()))); } @@ -134,7 +145,7 @@ class USymbolNode extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -144,8 +155,15 @@ class USymbolNode extends USymbol { ug = ug.apply(new UTranslate(-4, 11)); final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder()); - final double posStereo = (width - dimStereo.getWidth()) / 2; - stereotype.drawU(ug.apply(new UTranslate(posStereo, 2))); + final double posStereoX; + final double posStereoY = 2; + if (stereoAlignment == HorizontalAlignment.RIGHT) { + posStereoX = width - dimStereo.getWidth() - getMargin().getX1(); + } else { + posStereoX = (width - dimStereo.getWidth()) / 2; + + } + stereotype.drawU(ug.apply(new UTranslate(posStereoX, posStereoY))); final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); final double posTitle = (width - dimTitle.getWidth()) / 2; title.drawU(ug.apply(new UTranslate(posTitle, 2 + dimStereo.getHeight()))); diff --git a/src/net/sourceforge/plantuml/graphic/USymbolQueue.java b/src/net/sourceforge/plantuml/graphic/USymbolQueue.java index 799261720..010e330ef 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolQueue.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolQueue.java @@ -129,7 +129,7 @@ class USymbolQueue extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -153,7 +153,7 @@ class USymbolQueue extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolRect.java b/src/net/sourceforge/plantuml/graphic/USymbolRect.java index e5db9846f..3daae2265 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolRect.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolRect.java @@ -49,17 +49,17 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class USymbolRect extends USymbol { private final SkinParameter skinParameter; - private final HorizontalAlignment stereotypeAlignement; + // private final HorizontalAlignment stereotypeAlignement; - public USymbolRect(SkinParameter skinParameter, HorizontalAlignment stereotypeAlignement) { + public USymbolRect(SkinParameter skinParameter) { this.skinParameter = skinParameter; - this.stereotypeAlignement = stereotypeAlignement; +// this.stereotypeAlignement = stereotypeAlignement; } - @Override - public USymbol withStereoAlignment(HorizontalAlignment alignment) { - return new USymbolRect(skinParameter, alignment); - } +// @Override +// public USymbol withStereoAlignment(HorizontalAlignment alignment) { +// return new USymbolRect(skinParameter, alignment); +// } @Override public SkinParameter getSkinParameter() { @@ -96,7 +96,7 @@ class USymbolRect extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -106,7 +106,7 @@ class USymbolRect extends USymbol { drawRect(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(), symbolContext.getRoundCorner(), symbolContext.getDiagonalCorner()); final Margin margin = getMargin(); - final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereotypeAlignement); + final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment); tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1()))); } @@ -120,7 +120,7 @@ class USymbolRect extends USymbol { @Override public TextBlock asBig(final TextBlock title, final HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { final Dimension2D dim = calculateDimension(ug.getStringBounder()); @@ -130,7 +130,7 @@ class USymbolRect extends USymbol { final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder()); final double posStereoX; final double posStereoY; - if (stereotypeAlignement == HorizontalAlignment.RIGHT) { + if (stereoAlignment == HorizontalAlignment.RIGHT) { posStereoX = width - dimStereo.getWidth() - getMargin().getX1() / 2; posStereoY = getMargin().getY1() / 2; } else { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolSimpleAbstract.java b/src/net/sourceforge/plantuml/graphic/USymbolSimpleAbstract.java index 188569320..8e4162529 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolSimpleAbstract.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolSimpleAbstract.java @@ -45,7 +45,7 @@ abstract class USymbolSimpleAbstract extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { if (stereotype == null) { throw new IllegalArgumentException(); } @@ -83,7 +83,7 @@ abstract class USymbolSimpleAbstract extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/graphic/USymbolStack.java b/src/net/sourceforge/plantuml/graphic/USymbolStack.java index a672e9c91..a3d500069 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolStack.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolStack.java @@ -91,7 +91,7 @@ class USymbolStack extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -115,7 +115,7 @@ class USymbolStack extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/graphic/USymbolStorage.java b/src/net/sourceforge/plantuml/graphic/USymbolStorage.java index 39bd27101..05817599b 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolStorage.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolStorage.java @@ -65,7 +65,7 @@ class USymbolStorage extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -88,7 +88,7 @@ class USymbolStorage extends USymbol { @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolTogether.java b/src/net/sourceforge/plantuml/graphic/USymbolTogether.java index 37c5c5897..d7232d532 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolTogether.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolTogether.java @@ -49,13 +49,13 @@ class USymbolTogether extends USymbol { @Override public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, - final SymbolContext symbolContext) { + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return TextBlockUtils.empty(10, 10); } @Override public TextBlock asBig(final TextBlock title, HorizontalAlignment labelAlignment, final TextBlock stereotype, - final double width, final double height, final SymbolContext symbolContext) { + final double width, final double height, final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/jungle/GTileNode.java b/src/net/sourceforge/plantuml/jungle/GTileNode.java index c8717dea5..ada8adbe1 100644 --- a/src/net/sourceforge/plantuml/jungle/GTileNode.java +++ b/src/net/sourceforge/plantuml/jungle/GTileNode.java @@ -69,7 +69,7 @@ public class GTileNode extends AbstractTextBlock implements GTile { final SheetBlock1 sheetBlock1 = getTextBlock(display); final SymbolContext symbolContext = new SymbolContext(HtmlColorUtils.MY_YELLOW, HtmlColorUtils.BLACK); - tb = USymbol.RECTANGLE.asSmall(null, sheetBlock1, TextBlockUtils.empty(0, 0), symbolContext); + tb = USymbol.RECTANGLE.asSmall(null, sheetBlock1, TextBlockUtils.empty(0, 0), symbolContext, HorizontalAlignment.CENTER); } public static SheetBlock1 getTextBlock(final Display display) { diff --git a/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java b/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java index 232207d6c..0de1f5818 100644 --- a/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java +++ b/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java @@ -90,9 +90,8 @@ public class MindMapDiagram extends UmlDiagram { final double dpiFactor = scale == null ? getScaleCoef(fileFormatOption) : scale.getScale(100, 100); final ISkinParam skinParam = getSkinParam(); final ImageBuilder imageBuilder = new ImageBuilder(skinParam.getColorMapper(), dpiFactor, - skinParam.getBackgroundColor(), - fileFormatOption.isWithMetadata() ? getMetadata() : null, - "", 10, 10, null, skinParam.handwritten()); + skinParam.getBackgroundColor(), fileFormatOption.isWithMetadata() ? getMetadata() : null, "", 10, 10, + null, skinParam.handwritten()); TextBlock result = getTextBlock(); result = new AnnotatedWorker(this, skinParam, fileFormatOption.getDefaultStringBounder()).addAdd(result); diff --git a/src/net/sourceforge/plantuml/nwdiag/DiagElement.java b/src/net/sourceforge/plantuml/nwdiag/DiagElement.java index 7764aee35..afecba7b5 100644 --- a/src/net/sourceforge/plantuml/nwdiag/DiagElement.java +++ b/src/net/sourceforge/plantuml/nwdiag/DiagElement.java @@ -88,7 +88,7 @@ public class DiagElement { ColorParam.activityBorder.getDefaultValue()).withShadow(true); final TextBlock desc = toTextBlock(description); final TextBlock box = shape - .asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), symbolContext); + .asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), symbolContext, HorizontalAlignment.CENTER); return new LinkedElement(ad1, box, ad2, mainNetwork, this); } diff --git a/src/net/sourceforge/plantuml/preproc/EvalBoolean.java b/src/net/sourceforge/plantuml/preproc/EvalBoolean.java index 624dc4ad5..2f07a018e 100644 --- a/src/net/sourceforge/plantuml/preproc/EvalBoolean.java +++ b/src/net/sourceforge/plantuml/preproc/EvalBoolean.java @@ -116,7 +116,7 @@ public class EvalBoolean { } private boolean isIdentifier() { - return ch == '_' || Character.isLetterOrDigit(ch); + return ch == '_' || ch == '$' || Character.isLetterOrDigit(ch); } public boolean eval() { diff --git a/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java b/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java index 2593452df..b0010f7db 100644 --- a/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java +++ b/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java @@ -193,5 +193,9 @@ public class FileWithSuffix { public final String getSuffix() { return suffix; } + + public String toStringDebug() { + return file.getAbsolutePath(); + } } diff --git a/src/net/sourceforge/plantuml/preproc/Sub2.java b/src/net/sourceforge/plantuml/preproc/Sub2.java new file mode 100644 index 000000000..376d834f1 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/Sub2.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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.preproc; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterStartsub; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TLineType; +import net.sourceforge.plantuml.tim.TMemory; + +public class Sub2 { + + private final String name; + private final List lines = new ArrayList(); + + public Sub2(String name) { + this.name = name; + } + + public void add(StringLocated s) { + this.lines.add(s); + } + + public final List lines() { + return Collections.unmodifiableList(lines); + } + + public static Sub2 fromFile(ReadLine reader, String blocname, TContext context, TMemory memory) throws IOException, + EaterException { + Sub2 result = null; + StringLocated s = null; + while ((s = reader.readLine()) != null) { + final TLineType type = TLineType.getFromLine(s.getStringTrimmed()); + if (type == TLineType.STARTSUB) { + final EaterStartsub eater = new EaterStartsub(s.getStringTrimmed()); + eater.execute(context, memory); + if (eater.getSubname().equals(blocname)) { + result = new Sub2(blocname); + } + continue; + } + if (type == TLineType.ENDSUB && result != null) { + reader.close(); + return result; + } + if (result != null) { + result.add(s); + } + } + reader.close(); + return null; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc/Truth.java b/src/net/sourceforge/plantuml/preproc/Truth.java index 1b487102d..534df45b0 100644 --- a/src/net/sourceforge/plantuml/preproc/Truth.java +++ b/src/net/sourceforge/plantuml/preproc/Truth.java @@ -35,7 +35,7 @@ */ package net.sourceforge.plantuml.preproc; -interface Truth { +public interface Truth { public boolean isTrue(String name); } diff --git a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java index 6403e3968..95cf5cfae 100644 --- a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java +++ b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java @@ -48,13 +48,11 @@ public class UncommentReadLine extends ReadLineInstrumented implements ReadLine private static final Pattern2 unpause = MyPattern.cmpile(StartUtils.PAUSE_PATTERN); private final ReadLine raw; - // private final Pattern2 start; private String headerToRemove; private boolean paused; public UncommentReadLine(ReadLine source) { this.raw = source; - // this.start = MyPattern.cmpile(StartUtils.START_PATTERN); } @Override @@ -70,10 +68,6 @@ public class UncommentReadLine extends ReadLineInstrumented implements ReadLine return null; } - // final Matcher m = start.matcher(result); - // if (m.find()) { - // headerToRemove = m.group(1); - // } final String tmp = StartUtils.beforeStartUml(result.getString()); if (tmp != null) { headerToRemove = tmp; diff --git a/src/net/sourceforge/plantuml/preproc2/Preprocessor.java b/src/net/sourceforge/plantuml/preproc2/Preprocessor.java index 72a0be226..329408bcd 100644 --- a/src/net/sourceforge/plantuml/preproc2/Preprocessor.java +++ b/src/net/sourceforge/plantuml/preproc2/Preprocessor.java @@ -72,12 +72,12 @@ public class Preprocessor implements ReadLineNumbered { defines.saveState(); } final ReadFilterAnd filtersV2 = new ReadFilterAnd(); - filtersV2.add(new ReadLineQuoteComment()); - filtersV2.add(new SubPreprocessor(charset, definitionsContainer)); + filtersV2.add(new ReadLineQuoteComment(true)); + filtersV2.add(new ReadLineAddConfig(config)); this.sourceV2 = filtersV2.applyFilter(reader); final ReadFilterAnd filters = new ReadFilterAnd(); - filters.add(new ReadLineQuoteComment()); + filters.add(new ReadLineQuoteComment(false)); include = new PreprocessorInclude(config, charset, defines, definitionsContainer, importedFiles, filesUsedGlobal); filters.add(new ReadLineAddConfig(config)); diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java index bbd39f306..960401c76 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java @@ -69,6 +69,7 @@ import net.sourceforge.plantuml.preproc.ReadLineSimple; import net.sourceforge.plantuml.preproc.ReadLineSingle; import net.sourceforge.plantuml.preproc.StartDiagramExtractReader; import net.sourceforge.plantuml.preproc.Stdlib; +import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.utils.StartUtils; public class PreprocessorInclude implements ReadFilter { @@ -336,7 +337,7 @@ public class PreprocessorInclude implements ReadFilter { } } - public static ReadLine getReaderIncludeUrl(final URL url, StringLocated s, String suf, String charset) { + private static ReadLine getReaderIncludeUrl(final URL url, StringLocated s, String suf, String charset) { try { if (StartDiagramExtractReader.containsStartDiagram(url, s, charset)) { return StartDiagramExtractReader.build(url, s, suf, charset); @@ -355,6 +356,25 @@ public class PreprocessorInclude implements ReadFilter { } + public static ReadLine getReaderIncludeUrl2(final URL url, StringLocated s, String suf, String charset) throws EaterException { + try { + if (StartDiagramExtractReader.containsStartDiagram(url, s, charset)) { + return StartDiagramExtractReader.build(url, s, suf, charset); + } + final InputStream is = url.openStream(); + if (charset == null) { + Log.info("Using default charset"); + return ReadLineReader.create(new InputStreamReader(is), url.toString(), s.getLocation()); + } + Log.info("Using charset " + charset); + return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation()); + } catch (IOException e) { + e.printStackTrace(); + throw new EaterException("Cannot open URL"); + } + + } + public Set getFilesUsedGlobal() { return filesUsedGlobal; } diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorIncludeStrategy.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorIncludeStrategy.java index 0ea8936ac..45898b49a 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorIncludeStrategy.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorIncludeStrategy.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.preproc2; public enum PreprocessorIncludeStrategy { - ONCE, MANY; + ONCE, MANY, DEFAULT; public static PreprocessorIncludeStrategy fromString(String group) { if ("once".equalsIgnoreCase(group)) { diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java index db40f537a..41b07a954 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java @@ -44,6 +44,8 @@ public interface PreprocessorModeSet { public void setPreprocessorMode(PreprocessorMode mode); public ImportedFiles getImportedFiles(); + + public String getCharset(); } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java b/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java index 0b31444f4..41c7b670f 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java @@ -74,7 +74,7 @@ public class ReadLineAddConfig implements ReadFilter { } result = raw.readLine(); if (result != null && StartUtils.isArobaseStartDiagram(result.getString()) && config.size() > 0) { - inserted = new ReadLineQuoteComment().applyFilter(new ReadLineList(config, result.getLocation())); + inserted = new ReadLineQuoteComment(false).applyFilter(new ReadLineList(config, result.getLocation())); } return result; } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java b/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java index 6587c9ded..c4b7ab5f4 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java @@ -42,7 +42,17 @@ import net.sourceforge.plantuml.preproc.ReadLine; public class ReadLineQuoteComment implements ReadFilter { + private final boolean ignoreMe; + + public ReadLineQuoteComment(boolean ignoreMe) { + this.ignoreMe = ignoreMe; + } + public ReadLine applyFilter(final ReadLine source) { + if (ignoreMe) { + return source; + } + return new ReadLine() { public void close() throws IOException { diff --git a/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java b/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java index c1c375819..2e89353cf 100644 --- a/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java +++ b/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java @@ -178,7 +178,7 @@ public class SubPreprocessor implements ReadFilter { } private ReadLine getReaderIncludeWithoutComment(StringLocated s, final File f) { - return new ReadLineQuoteComment().applyFilter(getReaderIncludeRaw(s, f)); + return new ReadLineQuoteComment(false).applyFilter(getReaderIncludeRaw(s, f)); } private ReadLine getReaderIncludeRaw(StringLocated s, final File f) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java index 868ff130e..ac3ff26d2 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java @@ -209,11 +209,20 @@ public class CommandArrow extends SingleLineCommand2 { if (circleAtStart) { config = config.withDecoration1(ArrowDecoration.CIRCLE); } - if (dressing1.contains("x")) { - config = config.withHead2(ArrowHead.CROSSX); - } - if (dressing2.contains("x")) { - config = config.withHead2(ArrowHead.CROSSX); + if (reverseDefine) { + if (dressing1.contains("x")) { + config = config.withHead2(ArrowHead.CROSSX); + } + if (dressing2.contains("x")) { + config = config.withHead1(ArrowHead.CROSSX); + } + } else { + if (dressing1.contains("x")) { + config = config.withHead1(ArrowHead.CROSSX); + } + if (dressing2.contains("x")) { + config = config.withHead2(ArrowHead.CROSSX); + } } if (reverseDefine) { config = config.reverseDefine(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java index 775642f08..ad97dbb9a 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.VerticalAlignment; @@ -52,6 +53,7 @@ import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.skin.rose.AbstractComponentRoseArrow; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; public class CommunicationTile extends AbstractTile implements TileWithUpdateStairs, TileWithCallbackY { @@ -104,6 +106,15 @@ public class CommunicationTile extends AbstractTile implements TileWithUpdateSta private boolean isCreate() { return message.isCreate(); } + + private double getArrowThickness() { + final UStroke result = skinParam.getThickness(LineParam.sequenceArrow, null); + if (result == null) { + return 1; + } + return result.getThickness(); + } + private ArrowComponent getComponent(StringBounder stringBounder) { ArrowConfiguration arrowConfiguration = message.getArrowConfiguration(); @@ -113,9 +124,10 @@ public class CommunicationTile extends AbstractTile implements TileWithUpdateSta if (isReverse(stringBounder)) { arrowConfiguration = arrowConfiguration.reverse(); } + arrowConfiguration = arrowConfiguration.withThickness(getArrowThickness()); - final ArrowComponent comp = skin.createComponentArrow(arrowConfiguration, skinParam, - message.getLabelNumbered()); + final ArrowComponent comp = skin + .createComponentArrow(arrowConfiguration, skinParam, message.getLabelNumbered()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java index 434dd3b48..53d7c0cad 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java @@ -142,15 +142,25 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker { final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam(), oneOf(scale, dpiFactor), metadata, null, 3, 10, diagram.getAnimation()); - imageBuilder.setUDrawable(new UDrawable() { - public void drawU(UGraphic ug) { - drawInternal(ug, index); - } - }); + imageBuilder.setUDrawable(new Foo(index)); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, diagram.seed(), os); } + class Foo implements UDrawable { + + private final int index; + + Foo(int index) { + this.index = index; + } + + public void drawU(UGraphic ug) { + drawInternal(ug, index); + } + + } + private UGraphic goDownAndCenterForEnglobers(UGraphic ug) { ug = goDown(ug, title); ug = goDown(ug, header); diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDatabase.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDatabase.java index c7d4c01dc..b5733660d 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDatabase.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDatabase.java @@ -69,7 +69,7 @@ public class ComponentRoseDatabase extends AbstractTextualComponent { final SymbolContext symbolContext = new SymbolContext(biColor.getBackColor(), biColor.getForeColor()) .withStroke(new UStroke(1.5)).withShadow(biColor.getDeltaShadow() > 0); this.stickman = USymbol.DATABASE.asSmall(null, TextBlockUtils.empty(16, 17), - TextBlockUtils.empty(0, 0), symbolContext); + TextBlockUtils.empty(0, 0), symbolContext, HorizontalAlignment.CENTER); } @Override diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseQueue.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseQueue.java index 3e3f8c563..426896269 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseQueue.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseQueue.java @@ -65,7 +65,7 @@ public class ComponentRoseQueue extends AbstractTextualComponent { false, fontForStereotype, htmlColorForStereotype); this.head = head; this.stickman = USymbol.QUEUE.asSmall(TextBlockUtils.empty(0, 0), getTextBlock(), TextBlockUtils.empty(0, 0), - biColor); + biColor, HorizontalAlignment.CENTER); } @Override diff --git a/src/net/sourceforge/plantuml/stats/StatsUtilsIncrement.java b/src/net/sourceforge/plantuml/stats/StatsUtilsIncrement.java index 801c83ff8..cafbbb211 100644 --- a/src/net/sourceforge/plantuml/stats/StatsUtilsIncrement.java +++ b/src/net/sourceforge/plantuml/stats/StatsUtilsIncrement.java @@ -41,11 +41,11 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.prefs.Preferences; import net.sourceforge.plantuml.FileFormat; -import net.sourceforge.plantuml.PSystemError; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.directdot.PSystemDot; import net.sourceforge.plantuml.eggs.PSystemWelcome; +import net.sourceforge.plantuml.error.PSystemErrorUtils; import net.sourceforge.plantuml.math.PSystemMath; import net.sourceforge.plantuml.salt.PSystemSalt; import net.sourceforge.plantuml.stats.api.Stats; @@ -110,7 +110,7 @@ public class StatsUtilsIncrement { } private static String name(Class type) { - if (type == PSystemError.class) { + if (PSystemErrorUtils.isDiagramError(type)) { return "Error"; } if (type == ActivityDiagram3.class) { diff --git a/src/net/sourceforge/plantuml/suggest/SuggestEngine.java b/src/net/sourceforge/plantuml/suggest/SuggestEngine.java deleted file mode 100644 index b06864e75..000000000 --- a/src/net/sourceforge/plantuml/suggest/SuggestEngine.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ======================================================================== - * 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.suggest; - -import java.util.Iterator; - -import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.command.UmlDiagramFactory; -import net.sourceforge.plantuml.core.UmlSource; -import net.sourceforge.plantuml.version.IteratorCounter2; - -final public class SuggestEngine { - - private static final int LIMIT = 120; - - private final UmlDiagramFactory systemFactory; - - private final IteratorCounter2 it99; - - public SuggestEngine(UmlSource source, Object foo) { - throw new UnsupportedOperationException(); - } - - public SuggestEngine(UmlSource source, UmlDiagramFactory systemFactory) { -// this.systemFactory = systemFactory; -// this.it99 = source.iterator2(); -// final CharSequence startLine = it99.next(); -// if (StartUtils.isArobaseStartDiagram(startLine) == false) { - throw new UnsupportedOperationException(); -// } - } - - public SuggestEngineResult tryToSuggest(AbstractPSystem system) { - return executeUmlCommand(system); - } - - private SuggestEngineResult executeUmlCommand(AbstractPSystem system) { - throw new UnsupportedOperationException(); -// while (it99.hasNext()) { -// if (StartUtils.isArobaseEndDiagram(it99.peek())) { -// return SuggestEngineResult.SYNTAX_OK; -// } -// final SuggestEngineResult check = checkAndCorrect(); -// if (check.getStatus() != SuggestEngineStatus.SYNTAX_OK) { -// return check; -// } -// final CommandControl commandControl = systemFactory.isValid2(it99); -// if (commandControl == CommandControl.OK_PARTIAL) { -// systemFactory.goForwardMultiline(it99); -// // if (ok == false) { -// // return SuggestEngineResult.CANNOT_CORRECT; -// // } -// } else if (commandControl == CommandControl.OK) { -// it99.next(); -// // final Command cmd = new ProtectedCommand(systemFactory.createCommand(Arrays.asList(s))); -// // final CommandExecutionResult result = cmd.execute(system, Arrays.asList(s)); -// // if (result.isOk() == false) { -// // return SuggestEngineResult.CANNOT_CORRECT; -// // } -// } else { -// return SuggestEngineResult.CANNOT_CORRECT; -// } -// } -// return SuggestEngineResult.CANNOT_CORRECT; - } - - SuggestEngineResult checkAndCorrect() { - throw new UnsupportedOperationException(); -// final String incorrectLine = it99.peek().toString(); -// if (incorrectLine.length() > LIMIT) { -// return SuggestEngineResult.CANNOT_CORRECT; -// } -// final CommandControl commandControl = systemFactory.isValid2(it99); -// if (commandControl != CommandControl.NOT_OK) { -// return SuggestEngineResult.SYNTAX_OK; -// } -// -// if (StringUtils.trin(incorrectLine).startsWith("{") -// && systemFactory.isValid(BlocLines.single(it99.peekPrevious() + " {")) != CommandControl.NOT_OK) { -// return new SuggestEngineResult(it99.peekPrevious() + " {"); -// } -// -// final Collection> all = new ArrayList>(); -// all.add(new VariatorRemoveOneChar(incorrectLine)); -// all.add(new VariatorSwapLetter(incorrectLine)); -// // all.add(new VariatorAddOneCharBetweenWords(incorrectLine, ':')); -// all.add(new VariatorAddOneCharBetweenWords(incorrectLine, '-')); -// all.add(new VariatorAddOneCharBetweenWords(incorrectLine, ' ')); -// // all.add(new VariatorAddTwoChar(incorrectLine, '\"')); -// -// for (Iterator it2 : all) { -// final SuggestEngineResult result = tryThis(it2); -// if (result != null) { -// return result; -// } -// } -// return SuggestEngineResult.CANNOT_CORRECT; - } - - private SuggestEngineResult tryThis(Iterator it2) { - throw new UnsupportedOperationException(); -// while (it2.hasNext()) { -// final String newS = it2.next(); -// if (StringUtils.trin(newS).length() == 0) { -// continue; -// } -// final CommandControl commandControl = systemFactory.isValid2(replaceFirstLine(newS)); -// if (commandControl == CommandControl.OK) { -// return new SuggestEngineResult(newS); -// } -// } -// return null; - } - - private IteratorCounter2 replaceFirstLine(String s) { - throw new UnsupportedOperationException(); -// final List tmp = new ArrayList(); -// tmp.add(new CharSequence2(s, null)); -// final Iterator it3 = it99.cloneMe(); -// if (it3.hasNext()) { -// it3.next(); -// } -// while (it3.hasNext()) { -// tmp.add(new CharSequence2(it3.next(), null)); -// } -// return new IteratorCounter2Impl(tmp); - } -} diff --git a/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java b/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java deleted file mode 100644 index 3eec4a8d2..000000000 --- a/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ======================================================================== - * 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.suggest; - -import net.sourceforge.plantuml.StringUtils; - -public class SuggestEngineResult { - - private final SuggestEngineStatus status; - private final String suggestedLine; - - public static final SuggestEngineResult CANNOT_CORRECT = new SuggestEngineResult(SuggestEngineStatus.CANNOT_CORRECT); - public static final SuggestEngineResult SYNTAX_OK = new SuggestEngineResult(SuggestEngineStatus.SYNTAX_OK); - - private SuggestEngineResult(SuggestEngineStatus status) { - if (status == SuggestEngineStatus.ONE_SUGGESTION) { - throw new IllegalArgumentException(); - } - this.status = status; - this.suggestedLine = null; - } - - @Override - public String toString() { - return status + " " + suggestedLine; - } - - @Override - public int hashCode() { - return status.hashCode() + (suggestedLine == null ? 0 : suggestedLine.hashCode()); - } - - @Override - public boolean equals(Object obj) { - final SuggestEngineResult this2 = (SuggestEngineResult) obj; - return status.equals(this2.status) && sameString(suggestedLine, this2.suggestedLine); - } - - private static boolean sameString(String a, String b) { - return (a == null && b == null) || (a != null && a.equals(b)); - } - - public SuggestEngineResult(String suggestedLine) { - if (StringUtils.trin(suggestedLine).length() == 0) { - throw new IllegalArgumentException(); - } - this.status = SuggestEngineStatus.ONE_SUGGESTION; - this.suggestedLine = suggestedLine; - } - - public final SuggestEngineStatus getStatus() { - return status; - } - - public final String getSuggestedLine() { - return suggestedLine; - } - -} diff --git a/src/net/sourceforge/plantuml/svek/Cluster.java b/src/net/sourceforge/plantuml/svek/Cluster.java index 62fdcc6cc..5ba24a029 100644 --- a/src/net/sourceforge/plantuml/svek/Cluster.java +++ b/src/net/sourceforge/plantuml/svek/Cluster.java @@ -354,8 +354,9 @@ public class Cluster implements Moveable { } } - final boolean shadowing = group.getUSymbol() == null ? skinParam2.shadowing2(group.getStereotype(), USymbol.PACKAGE.getSkinParameter()) - : skinParam2.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()); + final boolean shadowing = group.getUSymbol() == null ? skinParam2.shadowing2(group.getStereotype(), + USymbol.PACKAGE.getSkinParameter()) : skinParam2.shadowing2(group.getStereotype(), group + .getUSymbol().getSkinParameter()); if (ztitle != null || zstereo != null) { final HtmlColor back = getBackColor(getBackColor(umlDiagramType), skinParam2, group.getStereotype()); final double roundCorner = group.getUSymbol() == null ? 0 : group.getUSymbol().getSkinParameter() @@ -365,7 +366,8 @@ public class Cluster implements Moveable { final ClusterDecoration decoration = new ClusterDecoration(style, group.getUSymbol(), ztitle, zstereo, minX, minY, maxX, maxY, stroke2); decoration.drawU(ug, back, borderColor, shadowing, roundCorner, - skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false)); + skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false), + skinParam2.getStereotypeAlignment()); return; } final URectangle rect = new URectangle(maxX - minX, maxY - minY); diff --git a/src/net/sourceforge/plantuml/svek/ClusterDecoration.java b/src/net/sourceforge/plantuml/svek/ClusterDecoration.java index f58e10eb5..e59738066 100644 --- a/src/net/sourceforge/plantuml/svek/ClusterDecoration.java +++ b/src/net/sourceforge/plantuml/svek/ClusterDecoration.java @@ -84,14 +84,14 @@ public class ClusterDecoration { public final static int marginTitleY2 = 3; public void drawU(UGraphic ug, HtmlColor backColor, HtmlColor borderColor, boolean shadowing, double roundCorner, - HorizontalAlignment titleAlignment) { + HorizontalAlignment titleAlignment, HorizontalAlignment stereoAlignment) { final SymbolContext biColor = new SymbolContext(backColor, borderColor); if (symbol == null) { throw new UnsupportedOperationException(); } final SymbolContext symbolContext = biColor.withShadow(shadowing).withStroke(defaultStroke) .withCorner(roundCorner, 0); - symbol.asBig(title, titleAlignment, stereo, maxX - minX, maxY - minY, symbolContext).drawU( + symbol.asBig(title, titleAlignment, stereo, maxX - minX, maxY - minY, symbolContext, stereoAlignment).drawU( ug.apply(new UTranslate(minX, minY))); } diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index a6adbec8e..a632ae99c 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -88,6 +88,7 @@ import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.svek.extremity.Extremity; import net.sourceforge.plantuml.svek.extremity.ExtremityFactory; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryExtends; +import net.sourceforge.plantuml.svek.extremity.ExtremityOther; import net.sourceforge.plantuml.svek.image.EntityImageNoteLink; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -95,7 +96,6 @@ import net.sourceforge.plantuml.ugraphic.UComment; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UPolygon; -import net.sourceforge.plantuml.ugraphic.UShape; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -524,12 +524,8 @@ public class Line implements Moveable, Hideable { }; } } else if (decor != LinkDecor.NONE) { - final UShape sh = new UPolygon(pointListIterator.next()); - return new UDrawable() { - public void drawU(UGraphic ug) { - ug.draw(sh); - } - }; + final UPolygon sh = new UPolygon(pointListIterator.next()); + return new ExtremityOther(sh); } return null; @@ -710,6 +706,21 @@ public class Line implements Moveable, Hideable { } } + if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) { + // http://forum.plantuml.net/9421/arrow-inversion-with-skinparam-linetype-ortho-missing-arrow + final Point2D p1 = ((Extremity) extremity1).isTooSmallSoGiveThePointCloserToThisOne(todraw + .getStartPoint()); + if (p1 != null) { + todraw.forceStartPoint(p1.getX(), p1.getY()); + } + final Point2D p2 = ((Extremity) extremity2).isTooSmallSoGiveThePointCloserToThisOne(todraw + .getEndPoint()); + if (p2 != null) { + todraw.forceEndPoint(p2.getX(), p2.getY()); + } + + } + final String comment = link.getEntity1().getCode().getFullName() + "-" + link.getEntity2().getCode().getFullName(); todraw.setComment(uniq(ids, comment)); diff --git a/src/net/sourceforge/plantuml/svek/extremity/Extremity.java b/src/net/sourceforge/plantuml/svek/extremity/Extremity.java index 9a88e1f23..23da0fd9e 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/Extremity.java +++ b/src/net/sourceforge/plantuml/svek/extremity/Extremity.java @@ -44,25 +44,25 @@ public abstract class Extremity implements UDrawable { protected double manageround(double angle) { final double deg = angle * 180.0 / Math.PI; - if (isCloseToo(0, deg)) { + if (isCloseTo(0, deg)) { return 0; } - if (isCloseToo(90, deg)) { + if (isCloseTo(90, deg)) { return 90.0 * Math.PI / 180.0; } - if (isCloseToo(180, deg)) { + if (isCloseTo(180, deg)) { return 180.0 * Math.PI / 180.0; } - if (isCloseToo(270, deg)) { + if (isCloseTo(270, deg)) { return 270.0 * Math.PI / 180.0; } - if (isCloseToo(360, deg)) { + if (isCloseTo(360, deg)) { return 0; } return angle; } - private boolean isCloseToo(double value, double variable) { + private boolean isCloseTo(double value, double variable) { if (Math.abs(value - variable) < 0.05) { return true; } @@ -70,5 +70,9 @@ public abstract class Extremity implements UDrawable { } public abstract Point2D somePoint(); + + public Point2D isTooSmallSoGiveThePointCloserToThisOne(Point2D pt) { + return null; + } } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java index 66c75e7ea..031ebe360 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityDiamond.java @@ -79,4 +79,15 @@ class ExtremityDiamond extends Extremity { ug.draw(polygon); } + @Override + public Point2D isTooSmallSoGiveThePointCloserToThisOne(Point2D pt) { + Point2D result = null; + for (Point2D p : polygon.getPoints()) { + if (result == null || p.distance(pt) < result.distance(pt)) { + result = p; + } + } + return result; + } + } diff --git a/src/net/sourceforge/plantuml/suggest/VariatorRemoveOneChar.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityOther.java similarity index 73% rename from src/net/sourceforge/plantuml/suggest/VariatorRemoveOneChar.java rename to src/net/sourceforge/plantuml/svek/extremity/ExtremityOther.java index 600ef3ab7..4bd7b8c09 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorRemoveOneChar.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityOther.java @@ -31,32 +31,30 @@ * * Original Author: Arnaud Roques * - * + * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.svek.extremity; -public class VariatorRemoveOneChar extends VariatorIteratorAdaptor { +import java.awt.geom.Point2D; - private final String data; - private int i; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPolygon; + +public class ExtremityOther extends Extremity { + + final private UPolygon polygon; + + public ExtremityOther(UPolygon polygon) { + this.polygon = polygon; + } + + public void drawU(UGraphic ug) { + ug.draw(polygon); - public VariatorRemoveOneChar(String data) { - this.data = data; } @Override - Variator getVariator() { - return new Variator() { - public String getData() { - if (i >= data.length()) { - return null; - } - return data.substring(0, i) + data.substring(i + 1); - } - - public void nextStep() { - i++; - } - }; + public Point2D somePoint() { + return polygon.getPoints().get(0); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java index b1d852de2..d839dd2dd 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java @@ -138,7 +138,7 @@ public class EntityImageDescription extends AbstractEntityImage { stereo = TextBlockUtils.empty(0, 0); if (stereotype != null && stereotype.getSprite(getSkinParam()) != null) { - symbol = symbol.withStereoAlignment(HorizontalAlignment.RIGHT); + // symbol = symbol.withStereoAlignment(HorizontalAlignment.RIGHT); stereo = stereotype.getSprite(getSkinParam()); } else if (stereotype != null && stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) != null && portionShower.showPortion(EntityPortion.STEREOTYPE, entity)) { @@ -152,9 +152,9 @@ public class EntityImageDescription extends AbstractEntityImage { if (hideText) { asSmall = symbol.asSmall(TextBlockUtils.empty(0, 0), TextBlockUtils.empty(0, 0), - TextBlockUtils.empty(0, 0), ctx); + TextBlockUtils.empty(0, 0), ctx, skinParam.getStereotypeAlignment()); } else { - asSmall = symbol.asSmall(name, desc, stereo, ctx); + asSmall = symbol.asSmall(name, desc, stereo, ctx, skinParam.getStereotypeAlignment()); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java index 97255661b..23f857b18 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java @@ -130,8 +130,9 @@ public class EntityImageEmptyPackage extends AbstractEntityImage { stereoBlock, 0, 0, widthTotal, heightTotal, getStroke()); decoration.drawU(ug, back, SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.packageBorder), - getSkinParam().shadowing(getEntity().getStereotype()), roundCorner, - getSkinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false)); + getSkinParam().shadowing(getEntity().getStereotype()), roundCorner, getSkinParam() + .getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false), getSkinParam() + .getStereotypeAlignment()); if (url != null) { ug.closeAction(); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java index 9358e918f..491390b85 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java @@ -95,7 +95,7 @@ public class EntityImageState2 extends AbstractEntityImage { final TextBlock desc = new BodyEnhanced(entity.getDisplay(), symbol.getFontParam(), skinParam, HorizontalAlignment.CENTER, stereotype, symbol.manageHorizontalLine(), false, entity); - asSmall = symbol.asSmall(null, desc, stereo, ctx); + asSmall = symbol.asSmall(null, desc, stereo, ctx, skinParam.getStereotypeAlignment()); } diff --git a/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java b/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java index 972635f0a..9d21c5de7 100644 --- a/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java +++ b/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java @@ -44,10 +44,10 @@ import net.sourceforge.plantuml.ErrorUml; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocationImpl; import net.sourceforge.plantuml.OptionFlags; -import net.sourceforge.plantuml.PSystemError; import net.sourceforge.plantuml.SourceStringReader; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.error.PSystemError; import net.sourceforge.plantuml.preproc.Defines; public class SyntaxChecker { @@ -68,17 +68,13 @@ public class SyntaxChecker { if (source.startsWith("@startuml\n") == false) { result.setError(true); result.setLineLocation(new LineLocationImpl("", null).oneLineRead()); - // result.setErrorLinePosition(0); result.addErrorText("No @startuml found"); - // result.setSuggest(Arrays.asList("Did you mean:", "@startuml")); return result; } if (source.endsWith("@enduml\n") == false && source.endsWith("@enduml") == false) { result.setError(true); result.setLineLocation(lastLineNumber2(source)); - // result.setErrorLinePosition(lastLineNumber(source)); result.addErrorText("No @enduml found"); - // result.setSuggest(Arrays.asList("Did you mean:", "@enduml")); return result; } final SourceStringReader sourceStringReader = new SourceStringReader(Defines.createEmpty(), source, @@ -88,9 +84,7 @@ public class SyntaxChecker { if (blocks.size() == 0) { result.setError(true); result.setLineLocation(lastLineNumber2(source)); - // result.setErrorLinePosition(lastLineNumber(source)); result.addErrorText("No @enduml found"); - // result.setSuggest(Arrays.asList("Did you mean:", "@enduml")); return result; } final Diagram system = blocks.get(0).getDiagram(); @@ -101,13 +95,11 @@ public class SyntaxChecker { } else if (system instanceof PSystemError) { result.setError(true); final PSystemError sys = (PSystemError) system; - // result.setErrorLinePosition(sys.getHigherErrorPosition()); result.setLineLocation(sys.getLineLocation()); result.setSystemError(sys); for (ErrorUml er : sys.getErrorsUml()) { result.addErrorText(er.getError()); } - // result.setSuggest(sys.getSuggest()); } else { result.setDescription(system.getDescription().getDescription()); } @@ -124,7 +116,6 @@ public class SyntaxChecker { result.setError(true); result.setLineLocation(lastLineNumber2(source)); result.addErrorText("No @enduml found"); - // result.setSuggest(Arrays.asList("Did you mean:", "@enduml")); return result; } @@ -136,13 +127,11 @@ public class SyntaxChecker { } else if (system instanceof PSystemError) { result.setError(true); final PSystemError sys = (PSystemError) system; - // result.setErrorLinePosition(sys.getHigherErrorPosition()); result.setLineLocation(sys.getLineLocation()); for (ErrorUml er : sys.getErrorsUml()) { result.addErrorText(er.getError()); } result.setSystemError(sys); - // result.setSuggest(sys.getSuggest()); } else { result.setDescription(system.getDescription().getDescription()); } diff --git a/src/net/sourceforge/plantuml/syntax/SyntaxResult.java b/src/net/sourceforge/plantuml/syntax/SyntaxResult.java index 473e8aafe..1581094bd 100644 --- a/src/net/sourceforge/plantuml/syntax/SyntaxResult.java +++ b/src/net/sourceforge/plantuml/syntax/SyntaxResult.java @@ -43,17 +43,15 @@ import java.util.TreeSet; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.PSystemError; import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.error.PSystemError; public class SyntaxResult { private UmlDiagramType umlDiagramType; private boolean isError; private String description; - // private int errorLinePosition; private Collection errors = new TreeSet(); - // private List suggest; private boolean hasCmapData; private PSystemError systemError; private LineLocation lineLocation; @@ -70,14 +68,6 @@ public class SyntaxResult { return description; } - // public int getErrorLinePosition() { - // return errorLinePosition; - // } - - // public List getSuggest() { - // return suggest; - // } - public Collection getErrors() { return Collections.unmodifiableCollection(errors); } @@ -94,18 +84,10 @@ public class SyntaxResult { this.description = description; } - // public void setErrorLinePosition(int errorLinePosition) { - // this.errorLinePosition = errorLinePosition; - // } - public void addErrorText(String error) { this.errors.add(error); } - // public void setSuggest(List suggest) { - // this.suggest = suggest; - // } - public final boolean hasCmapData() { return hasCmapData; } diff --git a/src/net/sourceforge/plantuml/tim/ConditionalContext.java b/src/net/sourceforge/plantuml/tim/ConditionalContext.java index f9135bc04..921335a89 100644 --- a/src/net/sourceforge/plantuml/tim/ConditionalContext.java +++ b/src/net/sourceforge/plantuml/tim/ConditionalContext.java @@ -37,9 +37,13 @@ package net.sourceforge.plantuml.tim; public class ConditionalContext { private boolean isTrue; + private boolean hasBeenBurn; private ConditionalContext(boolean isTrue) { this.isTrue = isTrue; + if (this.isTrue) { + hasBeenBurn = true; + } } public static ConditionalContext fromValue(boolean isTrue) { @@ -50,8 +54,25 @@ public class ConditionalContext { return isTrue; } + public void enteringElseIf() { + this.isTrue = false; + } + public void nowInElse() { - this.isTrue = !isTrue; + this.isTrue = !hasBeenBurn; + } + + public void nowInSomeElseIf() { + this.isTrue = true; + this.hasBeenBurn = true; + } + + public final boolean hasBeenBurn() { + return hasBeenBurn; + } + + public final void setHasBeenBurn(boolean hasBeenBurn) { + this.hasBeenBurn = hasBeenBurn; } } diff --git a/src/net/sourceforge/plantuml/tim/ConditionalContexts.java b/src/net/sourceforge/plantuml/tim/ConditionalContexts.java index 7471100a8..db8aee6dd 100644 --- a/src/net/sourceforge/plantuml/tim/ConditionalContexts.java +++ b/src/net/sourceforge/plantuml/tim/ConditionalContexts.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.tim; import java.util.Deque; import java.util.LinkedList; -public class ConditionalContexts { +public abstract class ConditionalContexts { private final Deque allIfs = new LinkedList(); @@ -53,4 +53,13 @@ public class ConditionalContexts { return allIfs.pollLast(); } + public boolean areAllIfOk() { + for (ConditionalContext conditionalContext : allIfs) { + if (conditionalContext.conditionIsOkHere() == false) { + return false; + } + } + return true; + } + } diff --git a/src/net/sourceforge/plantuml/tim/Eater.java b/src/net/sourceforge/plantuml/tim/Eater.java index cb3ca8924..f38d742be 100644 --- a/src/net/sourceforge/plantuml/tim/Eater.java +++ b/src/net/sourceforge/plantuml/tim/Eater.java @@ -132,7 +132,7 @@ public abstract class Eater { } } - final protected String eatAntGetVarname() throws EaterException { + final protected String eatAndGetVarname() throws EaterException { final StringBuilder varname = new StringBuilder("" + eatOneChar()); if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) { throw new EaterException("a002"); @@ -141,7 +141,7 @@ public abstract class Eater { return varname.toString(); } - final protected String eatAntGetFunctionName() throws EaterException { + final protected String eatAndGetFunctionName() throws EaterException { final StringBuilder varname = new StringBuilder("" + eatOneChar()); if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) { throw new EaterException("a003"); @@ -151,7 +151,7 @@ public abstract class Eater { } final public void skipSpaces() { - while (i < s.length() && Character.isSpaceChar(s.charAt(i))) { + while (i < s.length() && Character.isWhitespace(s.charAt(i))) { i++; } } @@ -193,6 +193,14 @@ public abstract class Eater { i++; } + final protected boolean safeCheckAndEatChar(char ch) throws EaterException { + if (i >= s.length() || s.charAt(i) != ch) { + return false; + } + i++; + return true; + } + final protected void optionallyEatChar(char ch) throws EaterException { if (i >= s.length() || s.charAt(i) != ch) { return; @@ -241,16 +249,21 @@ public abstract class Eater { } final protected TFunctionImpl eatDeclareFunction(TContext context, TMemory memory, boolean unquoted, - LineLocation location) throws EaterException { + LineLocation location, boolean allowNoParenthesis) throws EaterException { final List args = new ArrayList(); - final String functionName = eatAntGetFunctionName(); + final String functionName = eatAndGetFunctionName(); skipSpaces(); - checkAndEatChar('('); + if (safeCheckAndEatChar('(') == false) { + if (allowNoParenthesis) { + return new TFunctionImpl(functionName, args, unquoted); + } + throw new EaterException("Missing opening parenthesis"); + } while (true) { skipSpaces(); char ch = peekChar(); if (TLineType.isLetterOrUnderscoreOrDollar(ch)) { - final String varname = eatAntGetVarname(); + final String varname = eatAndGetVarname(); skipSpaces(); final TValue defValue; if (peekChar() == '=') { @@ -278,7 +291,7 @@ public abstract class Eater { final protected TFunctionImpl eatDeclareFunctionWithOptionalReturn(TContext context, TMemory memory, boolean unquoted, LineLocation location) throws EaterException { - final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location); + final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false); if (peekChar() == 'r') { checkAndEatChar("return"); skipSpaces(); diff --git a/src/net/sourceforge/plantuml/tim/EaterAffectation.java b/src/net/sourceforge/plantuml/tim/EaterAffectation.java index d0dacacff..cb64e15c7 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAffectation.java +++ b/src/net/sourceforge/plantuml/tim/EaterAffectation.java @@ -44,14 +44,21 @@ public class EaterAffectation extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!"); skipSpaces(); - final String varname = eatAntGetVarname(); + String varname = eatAndGetVarname(); + TVariableScope scope = null; skipSpaces(); + if (peekChar() != '=') { + scope = TVariableScope.valueOf(varname.toUpperCase()); + varname = eatAndGetVarname(); + skipSpaces(); + } checkAndEatChar('='); skipSpaces(); final TValue value = eatExpression(context, memory); - memory.put(varname, new TVariable(value)); + memory.putVariable(varname, new TVariable(value), scope); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java b/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java index 24effb6e5..7925f5d8c 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java +++ b/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java @@ -44,12 +44,18 @@ public class EaterAffectationDefine extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!define"); skipSpaces(); - final String varname = eatAntGetVarname(); + final String varname = eatAndGetVarname(); skipSpaces(); - final TValue value = TValue.fromString(eatAllToEnd()); - memory.put(varname, new TVariable(value)); + final String tmp = eatAllToEnd(); + final String tmp2 = context.applyFunctionsAndVariables(memory, tmp); + final TValue value = TValue.fromString(tmp2); + // if (memory instanceof TMemoryLocal) { + // memory = ((TMemoryLocal) memory).getGlobalForInternalUseOnly(); + // } + memory.putVariable(varname, new TVariable(value), TVariableScope.GLOBAL); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterAssert.java b/src/net/sourceforge/plantuml/tim/EaterAssert.java index caeb35f0d..c9095357f 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAssert.java +++ b/src/net/sourceforge/plantuml/tim/EaterAssert.java @@ -44,6 +44,7 @@ public class EaterAssert extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!assert"); skipSpaces(); final TValue value = eatExpressionStopAtColon(context, memory); diff --git a/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java b/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java index 4064d6fb5..3ba0d87ec 100644 --- a/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java +++ b/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java @@ -41,6 +41,7 @@ public class EaterDeclareFunction extends Eater { private TFunctionImpl function; private final LineLocation location; + private boolean finalFlag; public EaterDeclareFunction(StringLocated s) { super(s.getStringTrimmed()); @@ -49,21 +50,39 @@ public class EaterDeclareFunction extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!"); - final boolean unquoted; - if (peekChar() == 'u') { - checkAndEatChar("unquoted function"); - unquoted = true; - } else { - checkAndEatChar("function"); - unquoted = false; + boolean unquoted = false; + while (peekUnquoted() || peekFinal()) { + if (peekUnquoted()) { + checkAndEatChar("unquoted"); + skipSpaces(); + unquoted = true; + } else if (peekFinal()) { + checkAndEatChar("final"); + skipSpaces(); + finalFlag = true; + } } + checkAndEatChar("function"); skipSpaces(); function = eatDeclareFunctionWithOptionalReturn(context, memory, unquoted, location); } + private boolean peekUnquoted() { + return peekChar() == 'u'; + } + + private boolean peekFinal() { + return peekChar() == 'f' && peekCharN2() == 'i'; + } + public TFunctionImpl getFunction() { return function; } + public final boolean getFinalFlag() { + return finalFlag; + } + } diff --git a/src/net/sourceforge/plantuml/tim/EaterDumpMemory.java b/src/net/sourceforge/plantuml/tim/EaterDumpMemory.java new file mode 100644 index 000000000..c7f4337d8 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterDumpMemory.java @@ -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.tim; + +public class EaterDumpMemory extends Eater { + + public EaterDumpMemory(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); + checkAndEatChar("!dump_memory"); + skipSpaces(); + final String remain = this.eatAllToEnd(); + memory.dumpDebug(remain); + // final String logData = context.applyFunctionsAndVariables(memory, remain); + // Log.error(logData); + } + +} diff --git a/src/net/sourceforge/plantuml/suggest/VariatorAddOneChar.java b/src/net/sourceforge/plantuml/tim/EaterElseIf.java similarity index 70% rename from src/net/sourceforge/plantuml/suggest/VariatorAddOneChar.java rename to src/net/sourceforge/plantuml/tim/EaterElseIf.java index eb85ed511..4b8353337 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorAddOneChar.java +++ b/src/net/sourceforge/plantuml/tim/EaterElseIf.java @@ -5,12 +5,12 @@ * (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 @@ -31,34 +31,30 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim; -public class VariatorAddOneChar extends VariatorIteratorAdaptor { +import net.sourceforge.plantuml.tim.expression.TValue; - private final String data; - private final char toAdd; - private int i; +public class EaterElseIf extends Eater { - public VariatorAddOneChar(String data, char toAdd) { - this.data = data; - this.toAdd = toAdd; + private boolean booleanValue; + + public EaterElseIf(String s) { + super(s); } @Override - Variator getVariator() { - return new Variator() { - public String getData() { - if (i > data.length()) { - return null; - } - return data.substring(0, i) + toAdd + data.substring(i); - } - - public void nextStep() { - i++; - } - }; + public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); + checkAndEatChar("!elseif"); + skipSpaces(); + final TValue value = eatExpression(context, memory); + this.booleanValue = value.toBoolean(); } + + public boolean isTrue() { + return this.booleanValue; + } + } diff --git a/src/net/sourceforge/plantuml/tim/EaterException.java b/src/net/sourceforge/plantuml/tim/EaterException.java index f3d04567c..f4fb9dec8 100644 --- a/src/net/sourceforge/plantuml/tim/EaterException.java +++ b/src/net/sourceforge/plantuml/tim/EaterException.java @@ -34,16 +34,28 @@ */ package net.sourceforge.plantuml.tim; +import net.sourceforge.plantuml.StringLocated; + public class EaterException extends Exception { private final String message; + private final StringLocated location; + + public EaterException(String message, StringLocated location) { + this.message = message; + this.location = location; + } public EaterException(String message) { - this.message = message; + this(message, null); } public final String getMessage() { return message; } + public final StringLocated getLocation() { + return location; + } + } diff --git a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java index 2fb9e074d..adf740bf3 100644 --- a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java +++ b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java @@ -65,7 +65,11 @@ public class EaterFunctionCall extends Eater { while (true) { skipSpaces(); if (isLegacyDefine || unquoted) { - final TValue result = TValue.fromString(eatAndGetOptionalQuotedString()); + final String tmp = eatAndGetOptionalQuotedString(); + final String tmp2 = context.applyFunctionsAndVariables(memory, tmp); + // final TVariable var = memory.getVariable(tmp); + // final TValue result = var == null ? TValue.fromString(tmp) : var.getValue2(); + final TValue result = TValue.fromString(tmp2); values.add(result); } else { final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace(); @@ -85,24 +89,7 @@ public class EaterFunctionCall extends Eater { } } - private void executeLegacyDefine(TContext context, TMemory memory) throws EaterException { - while (true) { - skipSpaces(); - final TValue result = TValue.fromString(eatAndGetOptionalQuotedString()); - values.add(result); - skipSpaces(); - final char ch = eatOneChar(); - if (ch == ',') { - continue; - } - if (ch == ')') { - break; - } - throw new EaterException("call001"); - } - } - - public final List getValues2() { + public final List getValues() { return Collections.unmodifiableList(values); } diff --git a/src/net/sourceforge/plantuml/tim/EaterIf.java b/src/net/sourceforge/plantuml/tim/EaterIf.java index 4e50bc92a..d6ba6b261 100644 --- a/src/net/sourceforge/plantuml/tim/EaterIf.java +++ b/src/net/sourceforge/plantuml/tim/EaterIf.java @@ -46,6 +46,7 @@ public class EaterIf extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!if"); skipSpaces(); final TValue value = eatExpression(context, memory); diff --git a/src/net/sourceforge/plantuml/tim/EaterIfdef.java b/src/net/sourceforge/plantuml/tim/EaterIfdef.java index 05fba5bfd..ae52254da 100644 --- a/src/net/sourceforge/plantuml/tim/EaterIfdef.java +++ b/src/net/sourceforge/plantuml/tim/EaterIfdef.java @@ -34,9 +34,12 @@ */ package net.sourceforge.plantuml.tim; +import net.sourceforge.plantuml.preproc.EvalBoolean; +import net.sourceforge.plantuml.preproc.Truth; + public class EaterIfdef extends Eater { - private String varname; + private String expression; public EaterIfdef(String s) { super(s); @@ -44,14 +47,22 @@ public class EaterIfdef extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!ifdef"); skipSpaces(); - varname = eatAntGetVarname(); + expression = eatAllToEnd(); } - public boolean isTrue(TContext context, TMemory memory) { - final TVariable currentValue = memory.getVariable(varname); - return currentValue != null || context.doesFunctionExist(varname); + public boolean isTrue(final TContext context, final TMemory memory) { + final EvalBoolean eval = new EvalBoolean(expression, new Truth() { + + public boolean isTrue(String varname) { + final TVariable currentValue = memory.getVariable(varname); + return currentValue != null || context.doesFunctionExist(varname); + } + }); + + return eval.eval(); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterIfndef.java b/src/net/sourceforge/plantuml/tim/EaterIfndef.java index 0c5b8e472..cce7af168 100644 --- a/src/net/sourceforge/plantuml/tim/EaterIfndef.java +++ b/src/net/sourceforge/plantuml/tim/EaterIfndef.java @@ -44,9 +44,10 @@ public class EaterIfndef extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!ifndef"); skipSpaces(); - varname = eatAntGetVarname(); + varname = eatAndGetVarname(); } public boolean isTrue(TContext context, TMemory memory) { diff --git a/src/net/sourceforge/plantuml/tim/EaterImport.java b/src/net/sourceforge/plantuml/tim/EaterImport.java index 21f098777..bd368d115 100644 --- a/src/net/sourceforge/plantuml/tim/EaterImport.java +++ b/src/net/sourceforge/plantuml/tim/EaterImport.java @@ -44,6 +44,7 @@ public class EaterImport extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!import"); skipSpaces(); this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd()); diff --git a/src/net/sourceforge/plantuml/tim/EaterInclude.java b/src/net/sourceforge/plantuml/tim/EaterInclude.java index 59a4bae46..d88721bfc 100644 --- a/src/net/sourceforge/plantuml/tim/EaterInclude.java +++ b/src/net/sourceforge/plantuml/tim/EaterInclude.java @@ -34,9 +34,12 @@ */ package net.sourceforge.plantuml.tim; +import net.sourceforge.plantuml.preproc2.PreprocessorIncludeStrategy; + public class EaterInclude extends Eater { private String location; + private PreprocessorIncludeStrategy strategy = PreprocessorIncludeStrategy.DEFAULT; public EaterInclude(String s) { super(s); @@ -44,9 +47,21 @@ public class EaterInclude extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!include"); - if (peekChar() == 'u') { + final char peekChar = peekChar(); + if (peekChar == 'u') { checkAndEatChar("url"); + } else if (peekChar == '_') { + checkAndEatChar("_"); + final char peekChar2 = peekChar(); + if (peekChar2 == 'm') { + checkAndEatChar("many"); + this.strategy = PreprocessorIncludeStrategy.MANY; + } else { + checkAndEatChar("once"); + this.strategy = PreprocessorIncludeStrategy.ONCE; + } } skipSpaces(); this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd()); @@ -57,4 +72,8 @@ public class EaterInclude extends Eater { return location; } + public final PreprocessorIncludeStrategy getPreprocessorIncludeStrategy() { + return strategy; + } + } diff --git a/src/net/sourceforge/plantuml/suggest/VariatorSwapChar.java b/src/net/sourceforge/plantuml/tim/EaterIncludesub.java similarity index 71% rename from src/net/sourceforge/plantuml/suggest/VariatorSwapChar.java rename to src/net/sourceforge/plantuml/tim/EaterIncludesub.java index fb1241d46..27f94e320 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorSwapChar.java +++ b/src/net/sourceforge/plantuml/tim/EaterIncludesub.java @@ -5,12 +5,12 @@ * (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 @@ -31,32 +31,28 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim; -public class VariatorSwapChar extends VariatorIteratorAdaptor { +public class EaterIncludesub extends Eater { - private final String data; - private int i; + private String location; - public VariatorSwapChar(String data) { - this.data = data; + public EaterIncludesub(String s) { + super(s); } @Override - Variator getVariator() { - return new Variator() { - public String getData() { - if (i >= data.length() - 1) { - return null; - } - return data.substring(0, i) + data.charAt(i + 1) + data.charAt(i) + data.substring(i + 2); - } + public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); + checkAndEatChar("!includesub"); + skipSpaces(); + this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd()); - public void nextStep() { - i++; - } - }; } + + public final String getLocation() { + return location; + } + } diff --git a/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java b/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java index edd71c9c1..372151501 100644 --- a/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java +++ b/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java @@ -49,9 +49,10 @@ public class EaterLegacyDefine extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!define"); skipSpaces(); - function = eatDeclareFunction(context, memory, true, location); + function = eatDeclareFunction(context, memory, true, location, false); final String def = this.eatAllToEnd(); function.setFunctionType(TFunctionType.LEGACY_DEFINE); function.setLegacyDefinition(def); diff --git a/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java b/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java index 467c43338..79bfd1118 100644 --- a/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java +++ b/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java @@ -49,9 +49,10 @@ public class EaterLegacyDefineLong extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!definelong"); skipSpaces(); - function = eatDeclareFunction(context, memory, true, location); + function = eatDeclareFunction(context, memory, true, location, true); function.setFunctionType(TFunctionType.LEGACY_DEFINELONG); } diff --git a/src/net/sourceforge/plantuml/tim/EaterLog.java b/src/net/sourceforge/plantuml/tim/EaterLog.java new file mode 100644 index 000000000..f45a5147a --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterLog.java @@ -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.tim; + +import net.sourceforge.plantuml.Log; + +public class EaterLog extends Eater { + + public EaterLog(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); + checkAndEatChar("!log"); + skipSpaces(); + final String logData = context.applyFunctionsAndVariables(memory, this.eatAllToEnd()); + Log.error("[Log] " + logData); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterReturn.java b/src/net/sourceforge/plantuml/tim/EaterReturn.java index 48d55e61e..cce09b38c 100644 --- a/src/net/sourceforge/plantuml/tim/EaterReturn.java +++ b/src/net/sourceforge/plantuml/tim/EaterReturn.java @@ -46,6 +46,7 @@ public class EaterReturn extends Eater { @Override public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); checkAndEatChar("!return"); skipSpaces(); this.value = eatExpression(context, memory); diff --git a/src/net/sourceforge/plantuml/tim/EaterStartsub.java b/src/net/sourceforge/plantuml/tim/EaterStartsub.java new file mode 100644 index 000000000..3c0221fe9 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterStartsub.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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.tim; + +public class EaterStartsub extends Eater { + + private String subname; + + public EaterStartsub(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); + checkAndEatChar("!startsub"); + skipSpaces(); + this.subname = eatAllToEnd(); + if (this.subname.matches("\\w+") == false) { + throw new EaterException("Bad sub name"); + } + } + + public final String getSubname() { + return subname; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterUndef.java b/src/net/sourceforge/plantuml/tim/EaterUndef.java new file mode 100644 index 000000000..b97dd5eef --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterUndef.java @@ -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.tim; + +import net.sourceforge.plantuml.StringLocated; + +public class EaterUndef extends Eater { + + public EaterUndef(StringLocated s) { + super(s.getStringTrimmed()); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + skipSpaces(); + checkAndEatChar("!undef"); + skipSpaces(); + final String varname = eatAndGetVarname(); + memory.removeVariable(varname); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index 96c3f9939..c6d66b886 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -35,21 +35,17 @@ package net.sourceforge.plantuml.tim; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStreamReader; import java.io.Reader; -import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.FileSystem; -import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -58,26 +54,50 @@ import net.sourceforge.plantuml.preproc.FileWithSuffix; import net.sourceforge.plantuml.preproc.ImportedFiles; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineReader; +import net.sourceforge.plantuml.preproc.StartDiagramExtractReader; +import net.sourceforge.plantuml.preproc.Sub2; +import net.sourceforge.plantuml.preproc.UncommentReadLine; import net.sourceforge.plantuml.preproc2.PreprocessorInclude; +import net.sourceforge.plantuml.preproc2.PreprocessorIncludeStrategy; +import net.sourceforge.plantuml.preproc2.ReadLineQuoteComment; import net.sourceforge.plantuml.tim.expression.Knowledge; import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.tim.stdlib.AlwaysFalse; +import net.sourceforge.plantuml.tim.stdlib.AlwaysTrue; +import net.sourceforge.plantuml.tim.stdlib.CallUserFunction; import net.sourceforge.plantuml.tim.stdlib.DateFunction; import net.sourceforge.plantuml.tim.stdlib.Dirpath; import net.sourceforge.plantuml.tim.stdlib.FileExists; import net.sourceforge.plantuml.tim.stdlib.Filename; +import net.sourceforge.plantuml.tim.stdlib.FunctionExists; +import net.sourceforge.plantuml.tim.stdlib.GetVariableValue; import net.sourceforge.plantuml.tim.stdlib.Getenv; +import net.sourceforge.plantuml.tim.stdlib.IntVal; +import net.sourceforge.plantuml.tim.stdlib.InvokeVoidFunction; +import net.sourceforge.plantuml.tim.stdlib.LogicalNot; +import net.sourceforge.plantuml.tim.stdlib.SetVariableValue; import net.sourceforge.plantuml.tim.stdlib.Strlen; import net.sourceforge.plantuml.tim.stdlib.Strpos; import net.sourceforge.plantuml.tim.stdlib.Substr; +import net.sourceforge.plantuml.tim.stdlib.VariableExists; public class TContext { - private final ArrayList result = new ArrayList(); + private final List result = new ArrayList(); + private final List debug = new ArrayList(); private final Map functions2 = new HashMap(); + private final Set functionsFinal = new HashSet(); private final Trie functions3 = new Trie(); - private final ImportedFiles importedFiles; + private ImportedFiles importedFiles; + private final String charset; private TFunctionImpl pendingFunction; + private Sub2 pendingSub; + private boolean inLongComment; + private final Map subs = new HashMap(); + + // private final Set usedFiles = new HashSet(); + private final Set filesUsedCurrent = new HashSet(); private void addStandardFunctions(Defines defines) { addFunction(new Strlen()); @@ -88,11 +108,30 @@ public class TContext { addFunction(new Filename(defines)); addFunction(new DateFunction()); addFunction(new Strpos()); + addFunction(new InvokeVoidFunction()); + addFunction(new AlwaysFalse()); + addFunction(new AlwaysTrue()); + addFunction(new LogicalNot()); + addFunction(new FunctionExists()); + addFunction(new VariableExists()); + addFunction(new CallUserFunction()); + addFunction(new SetVariableValue()); + addFunction(new GetVariableValue()); + addFunction(new IntVal()); + // !exit + // !log + // %min + // %max + // Regexp + // %plantuml_version + // %time + // %trim + // %str_replace } - - public TContext(ImportedFiles importedFiles, Defines defines) { + public TContext(ImportedFiles importedFiles, Defines defines, String charset) { this.importedFiles = importedFiles; + this.charset = charset; this.addStandardFunctions(defines); } @@ -109,7 +148,7 @@ public class TContext { }; } - private TFunction getFunctionSmart(TFunctionSignature searched) { + public TFunction getFunctionSmart(TFunctionSignature searched) { final TFunction func = functions2.get(searched); if (func != null) { return func; @@ -125,69 +164,142 @@ public class TContext { return null; } - public CommandExecutionResult executeOneLine(TMemory memory, TLineType type, StringLocated s, TFunctionType fromType) { + public void executeOneLine(TMemory memory, TLineType type, StringLocated s, TFunctionType fromType) + throws EaterException { + + this.debug.add(s); + assert type == TLineType.getFromLine(s.getString()); + + if (this.inLongComment == false && type == TLineType.STARTSUB) { + if (pendingSub != null) { + throw new EaterException("Cannot nest sub"); + } + final EaterStartsub eater = new EaterStartsub(s.getStringTrimmed()); + eater.execute(this, memory); + this.pendingSub = new Sub2(eater.getSubname()); + this.subs.put(eater.getSubname(), this.pendingSub); + return; + } + if (this.inLongComment == false && type == TLineType.ENDSUB) { + if (pendingSub == null) { + throw new EaterException("No corresponding !startsub"); + } + final Sub2 newly = this.pendingSub; + this.pendingSub = null; + this.runSub(memory, newly); + return; + } + if (this.inLongComment == false && type == TLineType.INCLUDESUB) { + this.executeIncludesub(memory, s); + return; + } + + if (pendingSub != null) { + pendingSub.add(s); + return; + } + if (this.getPendingFunction() != null) { - if (type == TLineType.END_FUNCTION) { + if (this.inLongComment == false && type == TLineType.END_FUNCTION) { this.executeEndfunction(); } else { this.getPendingFunction().addBody(s); } - return CommandExecutionResult.ok(); - } - assert type == TLineType.getFromLine(s.getString()); - try { - - if (type == TLineType.ASSERT) { - return this.executeAssert(memory, s.getStringTrimmed()); - } else if (type == TLineType.IF) { - return this.executeIf(memory, s.getStringTrimmed()); - } else if (type == TLineType.IFDEF) { - return this.executeIfdef(memory, s.getStringTrimmed()); - } else if (type == TLineType.IFNDEF) { - return this.executeIfndef(memory, s.getStringTrimmed()); - } else if (type == TLineType.ELSE) { - return this.executeElse(memory, s.getStringTrimmed()); - } else if (type == TLineType.ENDIF) { - return this.executeEndif(memory, s.getStringTrimmed()); - } - - final ConditionalContext conditionalContext = memory.peekConditionalContext(); - if (conditionalContext != null && conditionalContext.conditionIsOkHere() == false) { - return CommandExecutionResult.ok(); - } - - if (fromType != TFunctionType.RETURN && type == TLineType.PLAIN) { - return this.addPlain(memory, s); - } else if (fromType == TFunctionType.RETURN && type == TLineType.RETURN) { - // Actually, ignore because we are in a if - return CommandExecutionResult.ok(); - } else if (type == TLineType.LEGACY_DEFINE) { - return this.executeLegacyDefine(memory, s); - } else if (type == TLineType.LEGACY_DEFINELONG) { - return this.executeLegacyDefineLong(memory, s); - } else if (type == TLineType.AFFECTATION_DEFINE) { - return this.executeAffectationDefine(memory, s.getStringTrimmed()); - } else if (type == TLineType.AFFECTATION) { - return this.executeAffectation(memory, s.getStringTrimmed()); - } else if (fromType == null && type == TLineType.DECLARE_FUNCTION) { - return this.executeDeclareFunction(memory, s); - } else if (fromType == null && type == TLineType.END_FUNCTION) { - return CommandExecutionResult.error("error endfunc"); - } else if (type == TLineType.INCLUDE) { - return this.executeInclude(memory, s); - } else if (type == TLineType.IMPORT) { - return this.executeImport(memory, s); - } else { - throw new UnsupportedOperationException("type=" + type + " fromType=" + fromType); - } - } catch (EaterException e) { - e.printStackTrace(); - return CommandExecutionResult.error(e.getMessage()); + return; } + if (this.inLongComment && s.getStringTrimmed().endsWith("'/")) { + this.inLongComment = false; + return; + } + + if (type == TLineType.COMMENT_LONG_START) { + this.inLongComment = true; + return; + } + if (this.inLongComment) { + return; + } + if (type == TLineType.COMMENT_SIMPLE) { + return; + } + s = s.removeInnerComment(); + + if (type == TLineType.IF) { + this.executeIf(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.IFDEF) { + this.executeIfdef(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.IFNDEF) { + this.executeIfndef(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.ELSE) { + this.executeElse(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.ELSEIF) { + this.executeElseIf(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.ENDIF) { + this.executeEndif(memory, s.getStringTrimmed()); + return; + } + + final ConditionalContext conditionalContext = memory.peekConditionalContext(); + if (conditionalContext != null && memory.areAllIfOk() == false) { + return; + } + + if (type == TLineType.DUMP_MEMORY) { + this.executeDumpMemory(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.ASSERT) { + this.executeAssert(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.UNDEF) { + this.executeUndef(memory, s); + return; + } else if (fromType != TFunctionType.RETURN && type == TLineType.PLAIN) { + this.addPlain(memory, s); + return; + } else if (fromType == TFunctionType.RETURN && type == TLineType.RETURN) { + // Actually, ignore because we are in a if + return; + } else if (type == TLineType.LEGACY_DEFINE) { + this.executeLegacyDefine(memory, s); + return; + } else if (type == TLineType.LEGACY_DEFINELONG) { + this.executeLegacyDefineLong(memory, s); + return; + } else if (type == TLineType.AFFECTATION_DEFINE) { + this.executeAffectationDefine(memory, s.getStringTrimmed()); + return; + } else if (type == TLineType.AFFECTATION) { + this.executeAffectation(memory, s.getStringTrimmed()); + return; + } else if (fromType == null && type == TLineType.DECLARE_FUNCTION) { + this.executeDeclareFunction(memory, s); + return; + } else if (fromType == null && type == TLineType.END_FUNCTION) { + CommandExecutionResult.error("error endfunc"); + return; + } else if (type == TLineType.INCLUDE) { + this.executeInclude(memory, s); + return; + } else if (type == TLineType.IMPORT) { + this.executeImport(memory, s); + return; + } else if (type == TLineType.LOG) { + this.executeLog(memory, s); + return; + } else { + // Thread.dumpStack(); + throw new EaterException("Parsing Error"); + // throw new UnsupportedOperationException("type=" + type + " fromType=" + fromType); + } } - private CommandExecutionResult addPlain(TMemory memory, StringLocated s) throws EaterException { + private void addPlain(TMemory memory, StringLocated s) throws EaterException { StringLocated tmp = applyFunctionsAndVariables(memory, s); if (tmp != null) { if (pendingAdd != null) { @@ -196,109 +308,130 @@ public class TContext { } result.add(tmp); } - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeAffectationDefine(TMemory memory, String s) throws EaterException { + private void executeAffectationDefine(TMemory memory, String s) throws EaterException { new EaterAffectationDefine(s).execute(this, memory); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeAffectation(TMemory memory, String s) throws EaterException { + private void executeAffectation(TMemory memory, String s) throws EaterException { new EaterAffectation(s).execute(this, memory); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeIf(TMemory memory, String s) throws EaterException { + private void executeIf(TMemory memory, String s) throws EaterException { final EaterIf condition = new EaterIf(s); condition.execute(this, memory); final boolean isTrue = condition.isTrue(); memory.addConditionalContext(ConditionalContext.fromValue(isTrue)); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeAssert(TMemory memory, String s) throws EaterException { + private void executeElseIf(TMemory memory, String s) throws EaterException { + final ConditionalContext poll = memory.peekConditionalContext(); + if (poll == null) { + throw new EaterException("No if related to this else"); + } + + poll.enteringElseIf(); + if (poll.hasBeenBurn() == false) { + final EaterElseIf condition = new EaterElseIf(s); + condition.execute(this, memory); + final boolean isTrue = condition.isTrue(); + if (isTrue) { + poll.nowInSomeElseIf(); + } + } + } + + private void executeDumpMemory(TMemory memory, String s) throws EaterException { + final EaterDumpMemory condition = new EaterDumpMemory(s); + condition.execute(this, memory); + } + + private void executeAssert(TMemory memory, String s) throws EaterException { final EaterAssert condition = new EaterAssert(s); condition.execute(this, memory); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeIfdef(TMemory memory, String s) throws EaterException { + private void executeIfdef(TMemory memory, String s) throws EaterException { final EaterIfdef condition = new EaterIfdef(s); condition.execute(this, memory); final boolean isTrue = condition.isTrue(this, memory); memory.addConditionalContext(ConditionalContext.fromValue(isTrue)); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeIfndef(TMemory memory, String s) throws EaterException { + private void executeIfndef(TMemory memory, String s) throws EaterException { final EaterIfndef condition = new EaterIfndef(s); condition.execute(this, memory); final boolean isTrue = condition.isTrue(this, memory); memory.addConditionalContext(ConditionalContext.fromValue(isTrue)); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeElse(TMemory memory, String s) throws EaterException { + private void executeElse(TMemory memory, String s) throws EaterException { final ConditionalContext poll = memory.peekConditionalContext(); if (poll == null) { - return CommandExecutionResult.error("No if related to this else"); + throw new EaterException("No if related to this else"); } poll.nowInElse(); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeEndif(TMemory memory, String s) throws EaterException { + private void executeEndif(TMemory memory, String s) throws EaterException { final ConditionalContext poll = memory.pollConditionalContext(); if (poll == null) { - return CommandExecutionResult.error("No if related to this endif"); + throw new EaterException("No if related to this endif"); } - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeDeclareFunction(TMemory memory, StringLocated s) throws EaterException { + private void executeDeclareFunction(TMemory memory, StringLocated s) throws EaterException { if (this.pendingFunction != null) { throw new EaterException("already0068"); } final EaterDeclareFunction declareFunction = new EaterDeclareFunction(s); declareFunction.execute(this, memory); - if (functions2.containsKey(declareFunction.getFunction().getSignature())) { - throw new EaterException("already0046"); + final boolean finalFlag = declareFunction.getFinalFlag(); + final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature(); + final TFunction previous = functions2.get(declaredSignature); + if (previous != null && (finalFlag || functionsFinal.contains(declaredSignature))) { + throw new EaterException("This function is already defined"); + } + if (finalFlag) { + functionsFinal.add(declaredSignature); } if (declareFunction.getFunction().hasBody()) { addFunction(declareFunction.getFunction()); } else { this.pendingFunction = declareFunction.getFunction(); } - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeLegacyDefine(TMemory memory, StringLocated s) throws EaterException { + private void executeUndef(TMemory memory, StringLocated s) throws EaterException { + final EaterUndef undef = new EaterUndef(s); + undef.execute(this, memory); + } + + private void executeLegacyDefine(TMemory memory, StringLocated s) throws EaterException { if (this.pendingFunction != null) { throw new EaterException("already0048"); } final EaterLegacyDefine legacyDefine = new EaterLegacyDefine(s); legacyDefine.execute(this, memory); final TFunction function = legacyDefine.getFunction(); - if (functions2.containsKey(function.getSignature())) { - throw new EaterException("already0047"); - } + // if (functions2.containsKey(function.getSignature())) { + // throw new EaterException("already0047"); + // } this.functions2.put(function.getSignature(), function); this.functions3.add(function.getSignature().getFunctionName() + "("); - return CommandExecutionResult.ok(); } - private CommandExecutionResult executeLegacyDefineLong(TMemory memory, StringLocated s) throws EaterException { + private void executeLegacyDefineLong(TMemory memory, StringLocated s) throws EaterException { if (this.pendingFunction != null) { throw new EaterException("already0068"); } final EaterLegacyDefineLong legacyDefineLong = new EaterLegacyDefineLong(s); legacyDefineLong.execute(this, memory); - if (functions2.containsKey(legacyDefineLong.getFunction().getSignature())) { - throw new EaterException("already0066"); - } + // if (functions2.containsKey(legacyDefineLong.getFunction().getSignature())) { + // throw new EaterException("already0066"); + // } this.pendingFunction = legacyDefineLong.getFunction(); - return CommandExecutionResult.ok(); } private StringLocated applyFunctionsAndVariables(TMemory memory, StringLocated located) throws EaterException { @@ -333,29 +466,32 @@ public class TContext { final EaterFunctionCall call = new EaterFunctionCall(sub, isLegacyDefine(presentFunction), isUnquoted(presentFunction)); call.execute(this, memory); - final TFunction function = getFunctionSmart(new TFunctionSignature(presentFunction, call.getValues2() + final TFunction function = getFunctionSmart(new TFunctionSignature(presentFunction, call.getValues() .size())); if (function == null) { throw new EaterException("Function not found " + presentFunction); } if (function.getFunctionType() == TFunctionType.VOID) { - function.executeVoid(this, sub, memory); + executeVoid3(memory, sub, function); return null; } if (function.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) { this.pendingAdd = s.substring(0, i); - function.executeVoid(this, sub, memory); + executeVoid3(memory, sub, function); return null; } assert function.getFunctionType() == TFunctionType.RETURN || function.getFunctionType() == TFunctionType.LEGACY_DEFINE; - final TValue functionReturn = function.executeReturn(this, memory, call.getValues2()); + final TValue functionReturn = function.executeReturn(this, memory, call.getValues()); result.append(functionReturn.toString()); i += call.getCurrentPosition() - 1; continue; } final String presentVariable = getVarnameAt(memory, s, i); if (presentVariable != null) { + if (result.toString().endsWith("##")) { + result.setLength(result.length() - 2); + } result.append(memory.getVariable(presentVariable).getValue2().toString()); i += presentVariable.length() - 1; if (i + 2 < s.length() && s.charAt(i + 1) == '#' && s.charAt(i + 2) == '#') { @@ -368,7 +504,11 @@ public class TContext { return result.toString(); } - private CommandExecutionResult executeImport(TMemory memory, StringLocated s) throws EaterException { + private void executeVoid3(TMemory memory, String s, TFunction function) throws EaterException { + function.executeVoid(this, memory, s); + } + + private void executeImport(TMemory memory, StringLocated s) throws EaterException { final EaterImport _import = new EaterImport(s.getStringTrimmed()); _import.execute(this, memory); @@ -377,20 +517,63 @@ public class TContext { applyFunctionsAndVariables(memory, _import.getLocation())); if (file.exists() && file.isDirectory() == false) { importedFiles.add(file); - return CommandExecutionResult.ok(); + return; } } catch (IOException e) { e.printStackTrace(); - return CommandExecutionResult.error("Cannot import " + e.getMessage()); + throw new EaterException("Cannot import " + e.getMessage()); } - return CommandExecutionResult.error("Cannot import"); + throw new EaterException("Cannot import"); } - private CommandExecutionResult executeInclude(TMemory memory, StringLocated s) throws EaterException { + private void executeLog(TMemory memory, StringLocated s) throws EaterException { + final EaterLog log = new EaterLog(s.getStringTrimmed()); + log.execute(this, memory); + } + + private void executeIncludesub(TMemory memory, StringLocated s) throws EaterException { + final EaterIncludesub include = new EaterIncludesub(s.getStringTrimmed()); + include.execute(this, memory); + final String location = include.getLocation(); + final int idx = location.indexOf('!'); + Sub2 sub = null; + if (OptionFlags.ALLOW_INCLUDE && idx != -1) { + final String filename = location.substring(0, idx); + final String blocname = location.substring(idx + 1); + try { + final FileWithSuffix f2 = new FileWithSuffix(importedFiles, filename, null); + if (f2.fileOk()) { + final Reader reader = f2.getReader(charset); + ReadLine readerline = ReadLineReader.create(reader, location, s.getLocation()); + readerline = new UncommentReadLine(readerline); + readerline = new ReadLineQuoteComment(true).applyFilter(readerline); + sub = Sub2.fromFile(readerline, blocname, this, memory); + } + } catch (IOException e) { + e.printStackTrace(); + throw new EaterException("cannot include " + e); + } + } else { + sub = subs.get(location); + } + if (sub == null) { + throw new EaterException("cannot include " + location); + } + runSub(memory, sub); + } + + private void runSub(TMemory memory, final Sub2 sub) throws EaterException { + for (StringLocated sl : sub.lines()) { + executeOneLine(memory, TLineType.getFromLine(sl.getString()), sl, null); + } + } + + private void executeInclude(TMemory memory, StringLocated s) throws EaterException { final EaterInclude include = new EaterInclude(s.getStringTrimmed()); include.execute(this, memory); String location = include.getLocation(); + final PreprocessorIncludeStrategy strategy = include.getPreprocessorIncludeStrategy(); final int idx = location.lastIndexOf('!'); String suf = null; if (idx != -1) { @@ -398,13 +581,12 @@ public class TContext { location = location.substring(0, idx); } - final String charset = null; - ReadLine reader2 = null; + ImportedFiles saveImportedFiles = null; try { if (location.startsWith("http://") || location.startsWith("https://")) { final URL url = new URL(location); - reader2 = PreprocessorInclude.getReaderIncludeUrl(url, s, suf, charset); + reader2 = PreprocessorInclude.getReaderIncludeUrl2(url, s, suf, charset); } if (location.startsWith("<") && location.endsWith(">")) { @@ -412,40 +594,48 @@ public class TContext { } else if (OptionFlags.ALLOW_INCLUDE) { final FileWithSuffix f2 = new FileWithSuffix(importedFiles, location, suf); if (f2.fileOk()) { - final Reader reader = f2.getReader(charset); - reader2 = ReadLineReader.create(reader, location, s.getLocation()); + if (strategy == PreprocessorIncludeStrategy.DEFAULT && filesUsedCurrent.contains(f2)) { + return; + } + if (strategy == PreprocessorIncludeStrategy.ONCE && filesUsedCurrent.contains(f2)) { + throw new EaterException("This file has already been included"); + } + + if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) { + reader2 = StartDiagramExtractReader.build(f2, s, charset); + } else { + final Reader reader = f2.getReader(charset); + reader2 = ReadLineReader.create(reader, location, s.getLocation()); + } + saveImportedFiles = this.importedFiles; + this.importedFiles = this.importedFiles.withCurrentDir(f2.getParentFile()); + assert reader2 != null; + filesUsedCurrent.add(f2); + // filesUsedGlobal.add(f2); } } if (reader2 != null) { - do { - final StringLocated sl = reader2.readLine(); - if (sl == null) { - return CommandExecutionResult.ok(); + reader2 = new ReadLineQuoteComment(true).applyFilter(reader2); + try { + do { + final StringLocated sl = reader2.readLine(); + if (sl == null) { + return; + } + executeOneLine(memory, TLineType.getFromLine(sl.getString()), sl, null); + } while (true); + } finally { + if (saveImportedFiles != null) { + this.importedFiles = saveImportedFiles; } - final CommandExecutionResult exe = executeOneLine(memory, TLineType.getFromLine(sl.getString()), - sl, null); - if (exe.isOk() == false) { - return exe; - } - } while (true); + } } } catch (IOException e) { e.printStackTrace(); - return CommandExecutionResult.error("cannot include " + e); + throw new EaterException("cannot include " + e); } - System.err.println("location=" + location); - return CommandExecutionResult.error("cannot include"); - } - - private Reader getReader(File file) throws FileNotFoundException, UnsupportedEncodingException { - final String charset = null; - if (charset == null) { - Log.info("Using default charset"); - return new InputStreamReader(new FileInputStream(file)); - } - Log.info("Using charset " + charset); - return new InputStreamReader(new FileInputStream(file), charset); + throw new EaterException("cannot include " + location); } public boolean isLegacyDefine(String functionName) { @@ -487,17 +677,6 @@ public class TContext { return null; } - private static String getVarnameAtOld(TMemory memory, String s, int pos) { - for (String varname : memory.variablesNames()) { - if (s.substring(pos).startsWith(varname)) - if (pos + varname.length() == s.length() - || Character.isLetterOrDigit(s.charAt(pos + varname.length())) == false) { - return varname; - } - } - return null; - } - private String getFunctionNameAt(String s, int pos) { final String fname = functions3.getLonguestMatchStartingIn(s.substring(pos)); if (fname.length() == 0) { @@ -506,22 +685,12 @@ public class TContext { return fname.substring(0, fname.length() - 1); } - private String getFunctionNameAtOld(String s, int pos) { - for (TFunctionSignature fname : functions2.keySet()) { - if (s.substring(pos).startsWith(fname.getFunctionName() + "(")) { - return fname.getFunctionName(); - } - } - return null; - } - public List getResult() { - return Collections.unmodifiableList(result); + return result; } - public List getResultWithError(StringLocated error) { - result.add(error); - return Collections.unmodifiableList(result); + public List getDebug() { + return debug; } public final TFunctionImpl getPendingFunction() { @@ -529,6 +698,9 @@ public class TContext { } private void addFunction(TFunction func) { + if (func.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) { + ((TFunctionImpl) func).finalizeEnddefinelong(); + } this.functions2.put(func.getSignature(), func); this.functions3.add(func.getSignature().getFunctionName() + "("); } diff --git a/src/net/sourceforge/plantuml/tim/TFunction.java b/src/net/sourceforge/plantuml/tim/TFunction.java index beb645cce..1bffbe0c4 100644 --- a/src/net/sourceforge/plantuml/tim/TFunction.java +++ b/src/net/sourceforge/plantuml/tim/TFunction.java @@ -46,10 +46,12 @@ public interface TFunction { public TFunctionType getFunctionType(); - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException; + public void executeVoid(TContext context, TMemory memory, String s) throws EaterException; public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException; + public void executeVoidInternal(TContext context, TMemory memory, List args) throws EaterException; + public boolean isUnquoted(); } diff --git a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java index 74b8be87d..6203523e5 100644 --- a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java +++ b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java @@ -35,10 +35,11 @@ package net.sourceforge.plantuml.tim; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.tim.expression.TValue; public class TFunctionImpl implements TFunction { @@ -80,30 +81,31 @@ public class TFunctionImpl implements TFunction { } } - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - if (functionType != TFunctionType.VOID && functionType != TFunctionType.LEGACY_DEFINELONG) { - throw new IllegalStateException(); - } + public void executeVoid(TContext context, TMemory memory, String s) throws EaterException { final EaterFunctionCall call = new EaterFunctionCall(s, context.isLegacyDefine(signature.getFunctionName()), unquoted); call.execute(context, memory); - final TMemory copy = getNewMemory(memory, call.getValues2()); - for (StringLocated sl : body) { - final CommandExecutionResult exe = context.executeOneLine(copy, TLineType.getFromLine(sl.getString()), sl, - TFunctionType.VOID); - if (exe.isOk() == false) { - throw new EaterException(exe.getError()); - } - } + final List args = call.getValues(); + executeVoidInternal(context, memory, args); + } + public void executeVoidInternal(TContext context, TMemory memory, List args) throws EaterException { + if (functionType != TFunctionType.VOID && functionType != TFunctionType.LEGACY_DEFINELONG) { + throw new IllegalStateException(); + } + final TMemory copy = getNewMemory(memory, args); + for (StringLocated sl : body) { + context.executeOneLine(copy, TLineType.getFromLine(sl.getString()), sl, TFunctionType.VOID); + } } private TMemory getNewMemory(TMemory memory, List values) { - final TMemory copy = memory.forkFromGlobal(); + final Map foo = new HashMap(); for (int i = 0; i < args.size(); i++) { final TValue tmp = i < values.size() ? values.get(i) : args.get(i).getOptionalDefaultValue(); - copy.put(args.get(i).getName(), new TVariable(tmp)); + foo.put(args.get(i).getName(), new TVariable(tmp)); } + final TMemory copy = memory.forkFromGlobal(foo); return copy; } @@ -126,10 +128,7 @@ public class TFunctionImpl implements TFunction { // System.err.println("s3=" + eaterReturn.getValue2()); return eaterReturn.getValue2(); } - final CommandExecutionResult exe = context.executeOneLine(copy, lineType, sl, TFunctionType.RETURN); - if (exe.isOk() == false) { - throw new EaterException(exe.getError()); - } + context.executeOneLine(copy, lineType, sl, TFunctionType.RETURN); } throw new EaterException("no return"); // return TValue.fromString("(NONE)"); @@ -141,6 +140,9 @@ public class TFunctionImpl implements TFunction { } final TMemory copy = getNewMemory(memory, args); final String tmp = context.applyFunctionsAndVariables(copy, legacyDefinition); + if (tmp == null) { + return TValue.fromString(""); + } return TValue.fromString(tmp); // eaterReturn.execute(context, copy); // // System.err.println("s3=" + eaterReturn.getValue2()); @@ -171,4 +173,14 @@ public class TFunctionImpl implements TFunction { return body.size() > 0; } + public void finalizeEnddefinelong() { + if (functionType != TFunctionType.LEGACY_DEFINELONG) { + throw new UnsupportedOperationException(); + } + if (body.size() == 1) { + this.functionType = TFunctionType.LEGACY_DEFINE; + this.legacyDefinition = body.get(0).getString(); + } + } + } diff --git a/src/net/sourceforge/plantuml/tim/TLineType.java b/src/net/sourceforge/plantuml/tim/TLineType.java index d8c6b3fc6..d7b22fc99 100644 --- a/src/net/sourceforge/plantuml/tim/TLineType.java +++ b/src/net/sourceforge/plantuml/tim/TLineType.java @@ -36,54 +36,84 @@ package net.sourceforge.plantuml.tim; public enum TLineType { - PLAIN, AFFECTATION_DEFINE, AFFECTATION, ASSERT, IF, IFDEF, IFNDEF, ELSE, ENDIF, DECLARE_FUNCTION, END_FUNCTION, RETURN, LEGACY_DEFINE, LEGACY_DEFINELONG, INCLUDE, IMPORT; + PLAIN, AFFECTATION_DEFINE, AFFECTATION, ASSERT, IF, IFDEF, UNDEF, IFNDEF, ELSE, ELSEIF, ENDIF, DECLARE_FUNCTION, END_FUNCTION, RETURN, LEGACY_DEFINE, LEGACY_DEFINELONG, INCLUDE, IMPORT, STARTSUB, ENDSUB, INCLUDESUB, LOG, DUMP_MEMORY, COMMENT_SIMPLE, COMMENT_LONG_START; public static TLineType getFromLine(String s) { - if (s.matches("^!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*")) { + if (s.matches("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*")) { return LEGACY_DEFINE; } - if (s.matches("^!definelong\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { + if (s.matches("^\\s*!definelong\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { return LEGACY_DEFINELONG; } - if (s.matches("^!define\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { + if (s.matches("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { return AFFECTATION_DEFINE; } - if (s.matches("^!\\s*\\$?[\\p{L}_][\\p{L}_0-9]*\\s*=.*")) { + if (s.matches("^\\s*!\\s*(local|global)?\\s*\\$?[\\p{L}_][\\p{L}_0-9]*\\s*=.*")) { return AFFECTATION; } - if (s.matches("^!ifdef\\s+.*")) { + if (s.matches("^\\s*'.*")) { + return COMMENT_SIMPLE; + } + if (s.matches("^\\s*/'.*'/\\s*$")) { + return COMMENT_SIMPLE; + } + if (s.matches("^\\s*/'.*") && s.contains("'/") == false) { + return COMMENT_LONG_START; + } + if (s.matches("^\\s*!ifdef\\s+.*")) { return IFDEF; } - if (s.matches("^!ifndef\\s+.*")) { + if (s.matches("^\\s*!undef\\s+.*")) { + return UNDEF; + } + if (s.matches("^\\s*!ifndef\\s+.*")) { return IFNDEF; } - if (s.matches("^!assert\\s+.*")) { + if (s.matches("^\\s*!assert\\s+.*")) { return ASSERT; } - if (s.matches("^!if\\s+.*")) { + if (s.matches("^\\s*!if\\s+.*")) { return IF; } - if (s.matches("^!(unquoted\\s)?function\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*")) { + if (s.matches("^\\s*!(unquoted\\s|final\\s)*function\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*")) { return DECLARE_FUNCTION; } - if (s.matches("^!else\\b.*")) { + if (s.matches("^\\s*!else\\b.*")) { return ELSE; } - if (s.matches("^!endif\\b.*")) { + if (s.matches("^\\s*!elseif\\b.*")) { + return ELSEIF; + } + if (s.matches("^\\s*!endif\\b.*")) { return ENDIF; } - if (s.matches("^!(endfunction|enddefinelong)\\b.*")) { + if (s.matches("^\\s*!(endfunction|enddefinelong)\\b.*")) { return END_FUNCTION; } - if (s.matches("^!return\\b.*")) { + if (s.matches("^\\s*!return\\b.*")) { return RETURN; } - if (s.matches("^!(include|includeurl)\\b.*")) { + if (s.matches("^\\s*!(include|includeurl|include_many|include_once)\\b.*")) { return INCLUDE; } - if (s.matches("^!(import)\\b.*")) { + if (s.matches("^\\s*!(import)\\b.*")) { return IMPORT; } + if (s.matches("^\\s*!startsub\\s+.*")) { + return STARTSUB; + } + if (s.matches("^\\s*!endsub\\b.*")) { + return ENDSUB; + } + if (s.matches("^\\s*!includesub\\b.*")) { + return INCLUDESUB; + } + if (s.matches("^\\s*!(log)\\b.*")) { + return LOG; + } + if (s.matches("^\\s*!(dump_memory)\\b.*")) { + return DUMP_MEMORY; + } return PLAIN; } diff --git a/src/net/sourceforge/plantuml/tim/TMemory.java b/src/net/sourceforge/plantuml/tim/TMemory.java index 3c9e50a83..048946a5a 100644 --- a/src/net/sourceforge/plantuml/tim/TMemory.java +++ b/src/net/sourceforge/plantuml/tim/TMemory.java @@ -34,13 +34,16 @@ */ package net.sourceforge.plantuml.tim; +import java.util.Map; import java.util.Set; public interface TMemory { public TVariable getVariable(String varname); - public void put(String varname, TVariable value); + public void putVariable(String varname, TVariable value, TVariableScope scope) throws EaterException; + + public void removeVariable(String varname); public boolean isEmpty(); @@ -48,11 +51,15 @@ public interface TMemory { public Trie variablesNames3(); - public TMemory forkFromGlobal(); + public TMemory forkFromGlobal(Map input); public ConditionalContext peekConditionalContext(); + public boolean areAllIfOk(); + public void addConditionalContext(ConditionalContext context); public ConditionalContext pollConditionalContext(); + + public void dumpDebug(String message); } diff --git a/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java b/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java index e1d8ed0af..5ec85c832 100644 --- a/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java +++ b/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java @@ -37,7 +37,12 @@ package net.sourceforge.plantuml.tim; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import java.util.TreeMap; + +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.tim.expression.TValue; public class TMemoryGlobal extends ConditionalContexts implements TMemory { @@ -48,11 +53,35 @@ public class TMemoryGlobal extends ConditionalContexts implements TMemory { return this.globalVariables.get(varname); } - public void put(String varname, TVariable value) { + public void dumpDebug(String message) { + Log.error("[MemGlobal] Start of memory_dump " + message); + dumpMemoryInternal(); + Log.error("[MemGlobal] End of memory_dump"); + } + + void dumpMemoryInternal() { + Log.error("[MemGlobal] Number of variable(s) : " + globalVariables.size()); + for (Entry ent : new TreeMap(globalVariables).entrySet()) { + final String name = ent.getKey(); + final TValue value = ent.getValue().getValue2(); + Log.error("[MemGlobal] " + name + " = " + value); + } + } + + public void putVariable(String varname, TVariable value, TVariableScope scope) throws EaterException { + Log.info("[MemGlobal] Setting " + varname); + if (scope == TVariableScope.LOCAL) { + throw new EaterException("Cannot use local variable here"); + } this.globalVariables.put(varname, value); this.variables.add(varname); } + public void removeVariable(String varname) { + this.globalVariables.remove(varname); + this.variables.remove(varname); + } + public boolean isEmpty() { return globalVariables.isEmpty(); } @@ -65,8 +94,8 @@ public class TMemoryGlobal extends ConditionalContexts implements TMemory { return variables; } - public TMemory forkFromGlobal() { - return new TMemoryLocal(this); + public TMemory forkFromGlobal(Map input) { + return new TMemoryLocal(this, input); } } diff --git a/src/net/sourceforge/plantuml/tim/TMemoryLocal.java b/src/net/sourceforge/plantuml/tim/TMemoryLocal.java index 441919d7f..8f4082333 100644 --- a/src/net/sourceforge/plantuml/tim/TMemoryLocal.java +++ b/src/net/sourceforge/plantuml/tim/TMemoryLocal.java @@ -37,60 +37,109 @@ package net.sourceforge.plantuml.tim; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import java.util.Map.Entry; + +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.tim.expression.TValue; public class TMemoryLocal extends ConditionalContexts implements TMemory { - private final TMemoryGlobal global; + private final TMemoryGlobal memoryGlobal; + private final Map overridenVariables = new HashMap(); private final Map localVariables = new HashMap(); - private Trie variables; - public TMemoryLocal(TMemoryGlobal global) { - this.global = global; + public TMemoryLocal(TMemoryGlobal global, Map input) { + this.memoryGlobal = global; + this.overridenVariables.putAll(input); + } + + public void dumpDebug(String message) { + Log.error("[MemLocal] Start of memory_dump " + message); + memoryGlobal.dumpMemoryInternal(); + Log.error("[MemLocal] Number of overriden variable(s) : " + overridenVariables.size()); + for (Entry ent : new TreeMap(overridenVariables).entrySet()) { + final String name = ent.getKey(); + final TValue value = ent.getValue().getValue2(); + Log.error("[MemLocal] " + name + " = " + value); + } + Log.error("[MemLocal] Number of local variable(s) : " + localVariables.size()); + for (Entry ent : new TreeMap(localVariables).entrySet()) { + final String name = ent.getKey(); + final TValue value = ent.getValue().getValue2(); + Log.error("[MemLocal] " + name + " = " + value); + } + Log.error("[MemGlobal] End of memory_dump"); } - private void initTrie() { - for (String name : global.variablesNames()) { - variables.add(name); + + public void putVariable(String varname, TVariable value, TVariableScope scope) throws EaterException { + if (scope == TVariableScope.GLOBAL) { + memoryGlobal.putVariable(varname, value, scope); + return; + } + if (scope == TVariableScope.LOCAL || overridenVariables.containsKey(varname)) { + this.overridenVariables.put(varname, value); + Log.info("[MemLocal/overrriden] Setting " + varname); + } else if (memoryGlobal.getVariable(varname) != null) { + memoryGlobal.putVariable(varname, value, scope); + } else { + this.localVariables.put(varname, value); + Log.info("[MemLocal/local] Setting " + varname); + } + } + + public void removeVariable(String varname) { + if (overridenVariables.containsKey(varname)) { + this.overridenVariables.remove(varname); + } else if (memoryGlobal.getVariable(varname) != null) { + memoryGlobal.removeVariable(varname); + } else { + this.localVariables.remove(varname); } } public TVariable getVariable(String varname) { - final TVariable result = localVariables.get(varname); + TVariable result = overridenVariables.get(varname); if (result != null) { return result; } - return global.getVariable(varname); + result = memoryGlobal.getVariable(varname); + if (result != null) { + return result; + } + result = localVariables.get(varname); + return result; } public Trie variablesNames3() { - if (variables == null) { - return global.variablesNames3(); + final Trie result = new Trie(); + for (String name : overridenVariables.keySet()) { + result.add(name); } - return variables; - } - - public void put(String varname, TVariable value) { - this.localVariables.put(varname, value); - if (this.variables == null) { - this.variables = new Trie(); - initTrie(); + for (String name : memoryGlobal.variablesNames()) { + result.add(name); } - this.variables.add(varname); + for (String name : localVariables.keySet()) { + result.add(name); + } + return result; } public boolean isEmpty() { - return global.isEmpty() && localVariables.isEmpty(); + return memoryGlobal.isEmpty() && localVariables.isEmpty() && overridenVariables.isEmpty(); } public Set variablesNames() { - // final Set result = new HashSet(localVariables.keySet()); - // result.addAll(global.variablesNames()); - // return Collections.unmodifiableSet(result); throw new UnsupportedOperationException(); } - public TMemory forkFromGlobal() { - return new TMemoryLocal(global); + public TMemory forkFromGlobal(Map input) { + return new TMemoryLocal(memoryGlobal, input); } + // public final TMemoryGlobal getGlobalForInternalUseOnly() { + // return memoryGlobal; + // } + } diff --git a/src/net/sourceforge/plantuml/suggest/Variator.java b/src/net/sourceforge/plantuml/tim/TVariableScope.java similarity index 91% rename from src/net/sourceforge/plantuml/suggest/Variator.java rename to src/net/sourceforge/plantuml/tim/TVariableScope.java index b220595f2..80edeccee 100644 --- a/src/net/sourceforge/plantuml/suggest/Variator.java +++ b/src/net/sourceforge/plantuml/tim/TVariableScope.java @@ -5,12 +5,12 @@ * (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 @@ -31,13 +31,10 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim; -public interface Variator { - - String getData(); - void nextStep(); +public enum TVariableScope { + LOCAL, GLOBAL } diff --git a/src/net/sourceforge/plantuml/tim/TimLoader.java b/src/net/sourceforge/plantuml/tim/TimLoader.java index 9323543a5..01e3c59a6 100644 --- a/src/net/sourceforge/plantuml/tim/TimLoader.java +++ b/src/net/sourceforge/plantuml/tim/TimLoader.java @@ -34,11 +34,9 @@ */ package net.sourceforge.plantuml.tim; -import java.util.ArrayList; import java.util.List; import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.preproc.ImportedFiles; @@ -46,26 +44,45 @@ public class TimLoader { private final TContext context; private final TMemory global = new TMemoryGlobal(); + private boolean preprocessorError; + private List result; - public TimLoader(ImportedFiles importedFiles, Defines defines) { - this.context = new TContext(importedFiles, defines); + public TimLoader(ImportedFiles importedFiles, Defines defines, String charset) { + this.context = new TContext(importedFiles, defines, charset); } - public List load(List input) { - for (StringLocated s : input) { - if (s.getPreprocessorError() != null) { - return new ArrayList(input); - } - } - + public void load(List input) { for (StringLocated s : input) { final TLineType type = TLineType.getFromLine(s.getStringTrimmed()); - final CommandExecutionResult exe = context.executeOneLine(global, type, s, null); - if (exe.isOk() == false) { - return context.getResultWithError(s.withErrorPreprocessor(exe.getError())); + try { + context.executeOneLine(global, type, s, null); + } catch (EaterException e) { + context.getResult().add(s.withErrorPreprocessor(e.getMessage())); + this.result = context.getResult(); + changeLastLine(context.getDebug(), e.getMessage()); + this.preprocessorError = true; + return; } } - return context.getResult(); + this.result = context.getResult(); + } + + private void changeLastLine(List list, String message) { + final int num = list.size() - 1; + final StringLocated last = list.get(num); + list.set(num, last.withErrorPreprocessor(message)); + } + + public final List getResult() { + return result; + } + + public final List getDebug() { + return context.getDebug(); + } + + public final boolean isPreprocessorError() { + return preprocessorError; } } diff --git a/src/net/sourceforge/plantuml/tim/Trie.java b/src/net/sourceforge/plantuml/tim/Trie.java index eb060fd2c..420aab1d9 100644 --- a/src/net/sourceforge/plantuml/tim/Trie.java +++ b/src/net/sourceforge/plantuml/tim/Trie.java @@ -41,26 +41,47 @@ public class Trie { private final Map brothers = new HashMap(); - private boolean terminalWord = false; - public void add(String s) { - add(this, s); + if (s.indexOf('\0') != -1) { + throw new IllegalArgumentException(); + } + addInternal(this, s + "\0"); } - private static void add(Trie current, String s) { + private static void addInternal(Trie current, String s) { if (s.length() == 0) { throw new UnsupportedOperationException(); } - while (s.length() > 0) { final Character added = s.charAt(0); final Trie child = current.getOrCreate(added); s = s.substring(1); - if (s.length() == 0) { - child.terminalWord = true; + current = child; + } + } + + public boolean remove(String s) { + return removeInternal(this, s + "\0"); + } + + private static boolean removeInternal(Trie current, String s) { + if (s.length() <= 1) { + throw new UnsupportedOperationException(); + } + while (s.length() > 0) { + final Character first = s.charAt(0); + final Trie child = current.brothers.get(first); + if (child == null) { + return false; + } + s = s.substring(1); + if (s.length() == 1) { + assert s.charAt(0) == '\0'; + return child.brothers.remove('\0') != null; } current = child; } + throw new IllegalStateException(); } private Trie getOrCreate(Character added) { @@ -80,15 +101,15 @@ public class Trie { final StringBuilder result = new StringBuilder(); while (current != null) { if (s.length() == 0) { - if (current.terminalWord) { + if (current.brothers.containsKey('\0')) { return result.toString(); } else { return ""; } } final Trie child = current.brothers.get(s.charAt(0)); - if (child == null) { - if (current.terminalWord) { + if (child == null || child.brothers.size() == 0) { + if (current.brothers.containsKey('\0')) { return result.toString(); } else { return ""; diff --git a/src/net/sourceforge/plantuml/tim/expression/TValue.java b/src/net/sourceforge/plantuml/tim/expression/TValue.java index 5cb8ddbc5..fd0df15cd 100644 --- a/src/net/sourceforge/plantuml/tim/expression/TValue.java +++ b/src/net/sourceforge/plantuml/tim/expression/TValue.java @@ -93,6 +93,13 @@ public class TValue { return new TValue(toString() + v2.toString()); } + public TValue minus(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return new TValue(this.intValue - v2.intValue); + } + return new TValue(toString() + v2.toString()); + } + public TValue multiply(TValue v2) { if (this.isNumber() && v2.isNumber()) { return new TValue(this.intValue * v2.intValue); @@ -100,6 +107,13 @@ public class TValue { return new TValue(toString() + v2.toString()); } + public TValue dividedBy(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return new TValue(this.intValue / v2.intValue); + } + return new TValue(toString() + v2.toString()); + } + public boolean isNumber() { return this.stringValue == null; } diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java b/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java index 5bbee81fd..97964ab4c 100644 --- a/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java +++ b/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java @@ -43,11 +43,21 @@ public enum TokenOperator { return v1.multiply(v2); } }, + DIVISION(100 - 3, "/") { + public TValue operate(TValue v1, TValue v2) { + return v1.dividedBy(v2); + } + }, ADDITION(100 - 4, "+") { public TValue operate(TValue v1, TValue v2) { return v1.add(v2); } }, + SUBSTRACTION(100 - 4, "-") { + public TValue operate(TValue v1, TValue v2) { + return v1.minus(v2); + } + }, LESS_THAN(100 - 6, "<") { public TValue operate(TValue v1, TValue v2) { return v1.lessThan(v2); diff --git a/src/net/sourceforge/plantuml/suggest/VariatorAddTwoChar.java b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java similarity index 64% rename from src/net/sourceforge/plantuml/suggest/VariatorAddTwoChar.java rename to src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java index d57627233..efdd0e50c 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorAddTwoChar.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java @@ -5,12 +5,12 @@ * (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 @@ -31,39 +31,28 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim.stdlib; -public class VariatorAddTwoChar extends VariatorIteratorAdaptor { +import java.util.List; - private final String data; - private final char toAdd; - private int i; - private int j = 1; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; - public VariatorAddTwoChar(String data, char toAdd) { - this.data = data; - this.toAdd = toAdd; +public class AlwaysFalse extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%false", 0); } - @Override - Variator getVariator() { - return new Variator() { - public String getData() { - if (i >= data.length()) { - return null; - } - return data.substring(0, i) + toAdd + data.substring(i, j) + toAdd + data.substring(j); - } + public boolean canCover(int nbArg) { + return nbArg == 0; + } - public void nextStep() { - j++; - if (j > data.length()) { - i++; - j = i + 1; - } - } - }; + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + return TValue.fromBoolean(false); } } diff --git a/src/net/sourceforge/plantuml/suggest/VariatorIteratorAdaptor.java b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java similarity index 65% rename from src/net/sourceforge/plantuml/suggest/VariatorIteratorAdaptor.java rename to src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java index 859925ad3..88a4f8df0 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorIteratorAdaptor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java @@ -5,12 +5,12 @@ * (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 @@ -31,38 +31,28 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim.stdlib; -import java.util.Iterator; -import java.util.NoSuchElementException; +import java.util.List; -public abstract class VariatorIteratorAdaptor implements Iterator { +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; - private final Variator variator; +public class AlwaysTrue extends SimpleReturnFunction { - abstract Variator getVariator(); - - public VariatorIteratorAdaptor() { - this.variator = getVariator(); + public TFunctionSignature getSignature() { + return new TFunctionSignature("%true", 0); } - public boolean hasNext() { - return variator.getData() != null; + public boolean canCover(int nbArg) { + return nbArg == 0; } - public String next() { - final String result = variator.getData(); - if (result == null) { - throw new NoSuchElementException(); - } - this.variator.nextStep(); - return result; + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + return TValue.fromBoolean(true); } - - public void remove() { - throw new UnsupportedOperationException(); - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java new file mode 100644 index 000000000..5021bf27e --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunction; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class CallUserFunction extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%call_user_func", 1); + } + + public boolean canCover(int nbArg) { + return nbArg > 0; + } + + public TValue executeReturn(TContext context, TMemory memory, List values) throws EaterException { + final String fname = values.get(0).toString(); + final List args = values.subList(1, values.size()); + final TFunctionSignature signature = new TFunctionSignature(fname, args.size()); + final TFunction func = context.getFunctionSmart(signature); + if (func == null) { + throw new EaterException("Cannot find void function " + fname); + } + return func.executeReturn(context, memory, args); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java index 4c444fcf6..9e89afb7b 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java @@ -40,13 +40,12 @@ import java.util.List; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.TContext; -import net.sourceforge.plantuml.tim.TFunction; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class DateFunction implements TFunction { +public class DateFunction extends SimpleReturnFunction { public TFunctionSignature getSignature() { return new TFunctionSignature("%date", 1); @@ -56,14 +55,6 @@ public class DateFunction implements TFunction { return nbArg == 0 || nbArg == 1; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { if (args.size() == 0) { return TValue.fromString(new Date().toString()); @@ -75,9 +66,4 @@ public class DateFunction implements TFunction { throw new EaterException("Bad date pattern"); } } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java b/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java index e65641114..8fbbd0bfc 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java @@ -47,7 +47,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class Dirpath implements TFunction { +public class Dirpath extends SimpleReturnFunction { private final String value; @@ -63,23 +63,10 @@ public class Dirpath implements TFunction { return nbArg == 0; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { if (value == null) { return TValue.fromString(""); } return TValue.fromString(value); } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java b/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java index 157bf02e8..a153f01c6 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java @@ -46,7 +46,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class FileExists implements TFunction { +public class FileExists extends SimpleReturnFunction { public TFunctionSignature getSignature() { return new TFunctionSignature("%file_exists", 1); @@ -56,14 +56,6 @@ public class FileExists implements TFunction { return nbArg == 1; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { if (OptionFlags.ALLOW_INCLUDE == false) { return TValue.fromBoolean(false); @@ -76,9 +68,4 @@ public class FileExists implements TFunction { final File f = new File(path); return f.exists(); } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Filename.java b/src/net/sourceforge/plantuml/tim/stdlib/Filename.java index d58c5d8d1..6f9038a6c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Filename.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Filename.java @@ -47,7 +47,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class Filename implements TFunction { +public class Filename extends SimpleReturnFunction { private final String value; @@ -63,23 +63,10 @@ public class Filename implements TFunction { return nbArg == 0; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { if (value == null) { return TValue.fromString(""); } return TValue.fromString(value); } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java b/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java new file mode 100644 index 000000000..93016d146 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class FunctionExists extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%function_exists", 1); + } + + public boolean canCover(int nbArg) { + return nbArg == 1; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + final String name = args.get(0).toString(); + return TValue.fromBoolean(context.doesFunctionExist(name)); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java new file mode 100644 index 000000000..2a4da96bb --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.TVariable; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class GetVariableValue extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%get_variable_value", 1); + } + + public boolean canCover(int nbArg) { + return nbArg == 1; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + final String name = args.get(0).toString(); + final TVariable variable = memory.getVariable(name); + if (variable == null) { + return TValue.fromString(""); + } + return variable.getValue2(); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java b/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java index 82fa48ecc..caac1deb7 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java @@ -46,7 +46,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class Getenv implements TFunction { +public class Getenv extends SimpleReturnFunction { public TFunctionSignature getSignature() { return new TFunctionSignature("%getenv", 1); @@ -56,14 +56,6 @@ public class Getenv implements TFunction { return nbArg == 1; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { if (OptionFlags.ALLOW_INCLUDE == false) { return TValue.fromString(""); @@ -84,9 +76,4 @@ public class Getenv implements TFunction { final String getenv = System.getenv(name); return getenv; } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/suggest/VariatorSwapLetter.java b/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java similarity index 59% rename from src/net/sourceforge/plantuml/suggest/VariatorSwapLetter.java rename to src/net/sourceforge/plantuml/tim/stdlib/IntVal.java index 5b400e1e3..5038e8220 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorSwapLetter.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java @@ -5,12 +5,12 @@ * (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 @@ -31,46 +31,35 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim.stdlib; -public class VariatorSwapLetter extends VariatorIteratorAdaptor { +import java.util.List; - private final String data; - private int i; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; - public VariatorSwapLetter(String data) { - this.data = data; - ensureTwoLetters(); +public class IntVal extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%intval", 1); } - private void ensureTwoLetters() { - while (i < data.length() - 1 && areTwoLetters() == false) { - i++; + public boolean canCover(int nbArg) { + return nbArg == 1; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + final String s = args.get(0).toString(); + try { + return TValue.fromInt(Integer.parseInt(s)); + } catch (Exception e) { + Log.error("Cannot convert " + s); } - - } - - private boolean areTwoLetters() { - return Character.isLetter(data.charAt(i)) && Character.isLetter(data.charAt(i + 1)); - - } - - @Override - Variator getVariator() { - return new Variator() { - public String getData() { - if (i >= data.length() - 1) { - return null; - } - return data.substring(0, i) + data.charAt(i + 1) + data.charAt(i) + data.substring(i + 2); - } - - public void nextStep() { - i++; - ensureTwoLetters(); - } - }; + return TValue.fromInt(0); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/InvokeVoidFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/InvokeVoidFunction.java new file mode 100644 index 000000000..a62bb66bf --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/InvokeVoidFunction.java @@ -0,0 +1,88 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterFunctionCall; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunction; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TFunctionType; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class InvokeVoidFunction implements TFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%invoke_void_func", 1); + } + + public boolean canCover(int nbArg) { + return nbArg > 0; + } + + public TFunctionType getFunctionType() { + return TFunctionType.VOID; + } + + public void executeVoid(TContext context, TMemory memory, String s) throws EaterException { + final EaterFunctionCall call = new EaterFunctionCall(s, false, isUnquoted()); + call.execute(context, memory); + final List values = call.getValues(); + final String fname = values.get(0).toString(); + final List args = values.subList(1, values.size()); + final TFunctionSignature signature = new TFunctionSignature(fname, args.size()); + final TFunction func = context.getFunctionSmart(signature); + if (func == null) { + throw new EaterException("Cannot find void function " + fname); + } + func.executeVoidInternal(context, memory, args); + } + + public void executeVoidInternal(TContext context, TMemory memory, List args) throws EaterException { + throw new UnsupportedOperationException(); + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + throw new UnsupportedOperationException(); + } + + public boolean isUnquoted() { + return false; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java new file mode 100644 index 000000000..7b62151c8 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class LogicalNot extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%not", 1); + } + + public boolean canCover(int nbArg) { + return nbArg == 1; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + final boolean arg = args.get(0).toBoolean(); + return TValue.fromBoolean(!arg); + } +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java new file mode 100644 index 000000000..e1d88693b --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.TVariable; +import net.sourceforge.plantuml.tim.TVariableScope; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class SetVariableValue extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%set_variable_value", 2); + } + + public boolean canCover(int nbArg) { + return nbArg == 2; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + // if (memory instanceof TMemoryLocal) { + // memory = ((TMemoryLocal) memory).getGlobalForInternalUseOnly(); + // } + final String name = args.get(0).toString(); + final TValue value = args.get(1); + memory.putVariable(name, new TVariable(value), TVariableScope.GLOBAL); + return TValue.fromString(""); + } + +} diff --git a/src/net/sourceforge/plantuml/suggest/VariatorAddOneCharBetweenWords.java b/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java similarity index 59% rename from src/net/sourceforge/plantuml/suggest/VariatorAddOneCharBetweenWords.java rename to src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java index c519116bc..3d3ca8bc0 100644 --- a/src/net/sourceforge/plantuml/suggest/VariatorAddOneCharBetweenWords.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java @@ -5,12 +5,12 @@ * (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 @@ -31,48 +31,36 @@ * * Original Author: Arnaud Roques * - * */ -package net.sourceforge.plantuml.suggest; +package net.sourceforge.plantuml.tim.stdlib; -public class VariatorAddOneCharBetweenWords extends VariatorIteratorAdaptor { +import java.util.List; - private final String data; - private final char toAdd; - private int i; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunction; +import net.sourceforge.plantuml.tim.TFunctionType; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; - public VariatorAddOneCharBetweenWords(String data, char toAdd) { - this.data = data; - this.toAdd = toAdd; - i++; - ensureBetweenWords(); +public abstract class SimpleReturnFunction implements TFunction { + + final public TFunctionType getFunctionType() { + return TFunctionType.RETURN; } - private void ensureBetweenWords() { - while (i < data.length() && inWord()) { - i++; - } - + final public void executeVoid(TContext context, TMemory memory, String s) throws EaterException { + throw new UnsupportedOperationException(); } - private boolean inWord() { - return Character.isLetterOrDigit(data.charAt(i - 1)) && Character.isLetterOrDigit(data.charAt(i)); + final public void executeVoidInternal(TContext context, TMemory memory, List args) throws EaterException { + throw new UnsupportedOperationException(); + } + + final public boolean isUnquoted() { + return false; } - @Override - Variator getVariator() { - return new Variator() { - public String getData() { - if (i > data.length() - 1) { - return null; - } - return data.substring(0, i) + toAdd + data.substring(i); - } - public void nextStep() { - i++; - ensureBetweenWords(); - } - }; - } + } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java index a0b2f1d52..fd030e1da 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java @@ -44,7 +44,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class Strlen implements TFunction { +public class Strlen extends SimpleReturnFunction { public TFunctionSignature getSignature() { return new TFunctionSignature("%strlen", 1); @@ -54,20 +54,7 @@ public class Strlen implements TFunction { return nbArg == 1; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { return TValue.fromInt(args.get(0).toString().length()); } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java b/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java index 0d620e5ad..8b8413521 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java @@ -44,7 +44,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class Strpos implements TFunction { +public class Strpos extends SimpleReturnFunction { public TFunctionSignature getSignature() { return new TFunctionSignature("%strpos", 2); @@ -54,22 +54,9 @@ public class Strpos implements TFunction { return nbArg == 2; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { final String full = args.get(0).toString(); final String searched = args.get(1).toString(); return TValue.fromInt(full.indexOf(searched)); } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Substr.java b/src/net/sourceforge/plantuml/tim/stdlib/Substr.java index 9635d8aff..b5352e298 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Substr.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Substr.java @@ -46,7 +46,7 @@ import net.sourceforge.plantuml.tim.TFunctionType; import net.sourceforge.plantuml.tim.TMemory; import net.sourceforge.plantuml.tim.expression.TValue; -public class Substr implements TFunction { +public class Substr extends SimpleReturnFunction { public TFunctionSignature getSignature() { return new TFunctionSignature("%substr", 3); @@ -56,14 +56,6 @@ public class Substr implements TFunction { return nbArg == 2 || nbArg == 3; } - public TFunctionType getFunctionType() { - return TFunctionType.RETURN; - } - - public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { - throw new UnsupportedOperationException(); - } - public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { final String full = args.get(0).toString(); final int pos = args.get(1).toInt(); @@ -79,9 +71,4 @@ public class Substr implements TFunction { } return TValue.fromString(result); } - - public boolean isUnquoted() { - return false; - } - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java b/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java new file mode 100644 index 000000000..116239137 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.util.List; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class VariableExists extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%variable_exists", 1); + } + + public boolean canCover(int nbArg) { + return nbArg == 1; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + final String name = args.get(0).toString(); + return TValue.fromBoolean(memory.getVariable(name) != null); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index 3255e2202..bc39eaca4 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -79,6 +79,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorSimple; import net.sourceforge.plantuml.graphic.HtmlColorTransparent; import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.mjpeg.MJPEGGenerator; import net.sourceforge.plantuml.skin.rose.Rose; @@ -277,11 +278,16 @@ public class ImageBuilder { } public Dimension2D getFinalDimension(StringBounder stringBounder) { - final LimitFinder limitFinder = new LimitFinder(stringBounder, true); - udrawable.drawU(limitFinder); - Dimension2D dim = new Dimension2DDouble(limitFinder.getMaxX() + 1 + margin1 + margin2 + externalMargin(), - limitFinder.getMaxY() + 1 + margin1 + margin2 + externalMargin()); - return dim; + final Dimension2D dim; +// if (udrawable instanceof TextBlock) { +// dim = ((TextBlock) udrawable).calculateDimension(stringBounder); +// } else { + final LimitFinder limitFinder = new LimitFinder(stringBounder, true); + udrawable.drawU(limitFinder); + dim = new Dimension2DDouble(limitFinder.getMaxX(), limitFinder.getMaxY()); +// } + return new Dimension2DDouble(dim.getWidth() + 1 + margin1 + margin2 + externalMargin(), dim.getHeight() + 1 + + margin1 + margin2 + externalMargin()); } private UGraphic handwritten(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/version/IteratorCounter2.java b/src/net/sourceforge/plantuml/version/IteratorCounter2.java index fe0fe6299..034b24acf 100644 --- a/src/net/sourceforge/plantuml/version/IteratorCounter2.java +++ b/src/net/sourceforge/plantuml/version/IteratorCounter2.java @@ -35,6 +35,7 @@ package net.sourceforge.plantuml.version; import java.util.Iterator; +import java.util.List; import net.sourceforge.plantuml.StringLocated; @@ -50,4 +51,6 @@ public interface IteratorCounter2 extends Iterator { public void copyStateFrom(IteratorCounter2 other); + public List getTrace(); + } diff --git a/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java b/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java index 4cedf154d..9af3e4538 100644 --- a/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java +++ b/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java @@ -34,6 +34,8 @@ */ package net.sourceforge.plantuml.version; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.StringLocated; @@ -41,21 +43,28 @@ import net.sourceforge.plantuml.StringLocated; public class IteratorCounter2Impl implements IteratorCounter2 { private List data; + private List trace; private int nb; public void copyStateFrom(IteratorCounter2 other) { final IteratorCounter2Impl source = (IteratorCounter2Impl) other; this.nb = source.nb; this.data = source.data; + this.trace = source.trace; } public IteratorCounter2Impl(List data) { - this(data, 0); + this(data, 0, new ArrayList()); } - private IteratorCounter2Impl(List data, int nb) { + private IteratorCounter2Impl(List data, int nb, List trace) { this.data = data; this.nb = nb; + this.trace = trace; + } + + public IteratorCounter2 cloneMe() { + return new IteratorCounter2Impl(data, nb, new ArrayList(trace)); } public int currentNum() { @@ -67,7 +76,10 @@ public class IteratorCounter2Impl implements IteratorCounter2 { } public StringLocated next() { - return data.get(nb++); + final StringLocated result = data.get(nb); + nb++; + trace.add(result); + return result; } public StringLocated peek() { @@ -85,8 +97,8 @@ public class IteratorCounter2Impl implements IteratorCounter2 { throw new UnsupportedOperationException(); } - public IteratorCounter2 cloneMe() { - return new IteratorCounter2Impl(data, nb); + public final List getTrace() { + return Collections.unmodifiableList(trace); } } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index b4d5e022f..a288db04a 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -43,7 +43,7 @@ public class Version { private static final int MAJOR_SEPARATOR = 1000000; public static int version() { - return 1201905; + return 1201906; } public static int versionPatched() { @@ -88,7 +88,7 @@ public class Version { } public static long compileTime() { - return 1555778736375L; + return 1558717825131L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/wbs/WBSDiagram.java b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java index c385d5152..860a12eb0 100644 --- a/src/net/sourceforge/plantuml/wbs/WBSDiagram.java +++ b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java @@ -80,7 +80,8 @@ public class WBSDiagram extends UmlDiagram { final double dpiFactor = scale == null ? getScaleCoef(fileFormatOption) : scale.getScale(100, 100); final ISkinParam skinParam = getSkinParam(); final ImageBuilder imageBuilder = new ImageBuilder(skinParam.getColorMapper(), dpiFactor, - skinParam.getBackgroundColor(), "", "", 10, 10, null, skinParam.handwritten()); + skinParam.getBackgroundColor(), fileFormatOption.isWithMetadata() ? getMetadata() : null, "", 10, 10, + null, skinParam.handwritten()); TextBlock result = getTextBlock(); result = new AnnotatedWorker(this, skinParam, fileFormatOption.getDefaultStringBounder()).addAdd(result); diff --git a/stdlib/awslib-abx.repx b/stdlib/awslib-abx.repx new file mode 100644 index 000000000..34b449f3a Binary files /dev/null and b/stdlib/awslib-abx.repx differ diff --git a/stdlib/awslib-dex.repx b/stdlib/awslib-dex.repx new file mode 100644 index 000000000..81df2e812 Binary files /dev/null and b/stdlib/awslib-dex.repx differ diff --git a/stdlib/home.repx b/stdlib/home.repx index c42df4086..4895d7746 100644 --- a/stdlib/home.repx +++ b/stdlib/home.repx @@ -1,5 +1,6 @@ azure aws +awslib cloudinsight cloudogu tupadr3