diff --git a/build.xml b/build.xml index eff604596..a14326d8d 100644 --- a/build.xml +++ b/build.xml @@ -69,7 +69,7 @@ - + diff --git a/pom.xml b/pom.xml index 559d0d61b..61b78186a 100644 --- a/pom.xml +++ b/pom.xml @@ -30,13 +30,12 @@ Script Author: Julien Eluard --> - + 4.0.0 net.sourceforge.plantuml plantuml - 1.2019.2-SNAPSHOT + 1.2019.5-SNAPSHOT jar PlantUML diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index 5f6db3042..f50c0983c 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -48,18 +48,21 @@ import net.sourceforge.plantuml.code.TranscoderUtil; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.preproc.Defines; +import net.sourceforge.plantuml.preproc2.PreprocessorMode; +import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; +import net.sourceforge.plantuml.tim.TimLoader; import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.version.Version; public class BlockUml { - private final List data; + private final List data; private Diagram system; private final Defines localDefines; private final ISkinSimple skinParam; BlockUml(String... strings) { - this(convert(strings), Defines.createEmpty(), null); + this(convert(strings), Defines.createEmpty(), null, null); } public String getEncodedUrl() throws IOException { @@ -71,43 +74,47 @@ public class BlockUml { public String getFlashData() { final StringBuilder sb = new StringBuilder(); - for (CharSequence2 line : data) { - sb.append(line); + for (StringLocated line : data) { + sb.append(line.getString()); sb.append('\r'); sb.append(BackSlash.CHAR_NEWLINE); } return sb.toString(); } - public static List convert(String... strings) { + public static List convert(String... strings) { return convert(Arrays.asList(strings)); } - public static List convert(List strings) { - final List result = new ArrayList(); + public static List convert(List strings) { + final List result = new ArrayList(); LineLocationImpl location = new LineLocationImpl("block", null); for (String s : strings) { location = location.oneLineRead(); - result.add(new CharSequence2Impl(s, location)); + result.add(new StringLocated(s, location)); } return result; } - public BlockUml(List strings, Defines defines, ISkinSimple skinParam) { + public BlockUml(List strings, Defines defines, ISkinSimple skinParam, PreprocessorModeSet mode) { this.localDefines = defines; this.skinParam = skinParam; - final CharSequence2 s0 = strings.get(0).trin(); + final String s0 = strings.get(0).getStringTrimmed(); if (StartUtils.startsWithSymbolAnd("start", s0) == false) { throw new IllegalArgumentException(); } - this.data = new ArrayList(strings); + if (mode != null && mode.getPreprocessorMode() == PreprocessorMode.V2_NEW_TIM) { + this.data = new TimLoader(mode.getImportedFiles()).load(strings); + } else { + this.data = new ArrayList(strings); + } } public String getFileOrDirname() { if (OptionFlags.getInstance().isWord()) { return null; } - final Matcher2 m = StartUtils.patternFilename.matcher(StringUtils.trin(data.get(0).toString())); + final Matcher2 m = StartUtils.patternFilename.matcher(StringUtils.trin(data.get(0).getString())); final boolean ok = m.find(); if (ok == false) { return null; @@ -137,7 +144,7 @@ public class BlockUml { return system; } - public final List getData() { + public final List getData() { return data; } @@ -145,8 +152,8 @@ public class BlockUml { try { final AsciiEncoder coder = new AsciiEncoder(); final MessageDigest msgDigest = MessageDigest.getInstance("MD5"); - for (CharSequence s : data) { - msgDigest.update(s.toString().getBytes("UTF-8")); + for (StringLocated s : data) { + msgDigest.update(s.getString().getBytes("UTF-8")); } final byte[] digest = msgDigest.digest(); return coder.encode(digest); @@ -166,14 +173,18 @@ public class BlockUml { public boolean isStartDef(String name) { final String signature = "@startdef(id=" + name + ")"; - return data.get(0).toString().equalsIgnoreCase(signature); + return data.get(0).getString().equalsIgnoreCase(signature); } - public List getDefinition(boolean withHeader) { - if (withHeader) { - return Collections.unmodifiableList(data); + public List getDefinition(boolean withHeader) { + final List data2 = new ArrayList(); + for (StringLocated s : data) { + data2.add(s.getString()); } - return Collections.unmodifiableList(data.subList(1, data.size() - 1)); + if (withHeader) { + return Collections.unmodifiableList(data2); + } + return Collections.unmodifiableList(data2.subList(1, data2.size() - 1)); } public Defines getLocalDefines() { diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java index 6f07791ec..1cf84c1cb 100644 --- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -45,30 +45,35 @@ import java.util.List; import java.util.Set; import net.sourceforge.plantuml.preproc.Defines; -import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.FileWithSuffix; import net.sourceforge.plantuml.preproc.ImportedFiles; +import net.sourceforge.plantuml.preproc.PreprocessorChangeModeReader; import net.sourceforge.plantuml.preproc.ReadLineNumbered; import net.sourceforge.plantuml.preproc.ReadLineReader; import net.sourceforge.plantuml.preproc.UncommentReadLine; -import net.sourceforge.plantuml.preproc2.Preprocessor2; +import net.sourceforge.plantuml.preproc2.Preprocessor; +import net.sourceforge.plantuml.preproc2.PreprocessorMode; import net.sourceforge.plantuml.utils.StartUtils; public final class BlockUmlBuilder implements DefinitionsContainer { + private PreprocessorMode mode = PreprocessorMode.V1_LEGACY; + private final List blocks = new ArrayList(); private Set usedFiles = new HashSet(); private final UncommentReadLine reader2; private final Defines defines; + private final ImportedFiles importedFiles; public BlockUmlBuilder(List config, String charset, Defines defines, Reader reader, File newCurrentDir, String desc) throws IOException { ReadLineNumbered includer = null; this.defines = defines; try { - reader2 = new UncommentReadLine(ReadLineReader.create(reader, desc)); - includer = new Preprocessor2(config, reader2, charset, defines, this, - ImportedFiles.createImportedFiles(new AParentFolderRegular(newCurrentDir))); + this.reader2 = new UncommentReadLine(new PreprocessorChangeModeReader(ReadLineReader.create(reader, desc), + this)); + this.importedFiles = ImportedFiles.createImportedFiles(new AParentFolderRegular(newCurrentDir)); + includer = new Preprocessor(config, reader2, charset, defines, this, importedFiles); init(includer); } finally { if (includer != null) { @@ -83,41 +88,41 @@ public final class BlockUmlBuilder implements DefinitionsContainer { } private void init(ReadLineNumbered includer) throws IOException { - CharSequence2 s = null; - List current2 = null; + StringLocated s = null; + List current2 = null; boolean paused = false; while ((s = includer.readLine()) != null) { - if (StartUtils.isArobaseStartDiagram(s)) { - current2 = new ArrayList(); + if (StartUtils.isArobaseStartDiagram(s.getString())) { + current2 = new ArrayList(); paused = false; } - if (StartUtils.isArobasePauseDiagram(s)) { + if (StartUtils.isArobasePauseDiagram(s.getString())) { paused = true; reader2.setPaused(true); } - if (StartUtils.isExit(s)) { + if (StartUtils.isExit(s.getString())) { paused = true; reader2.setPaused(true); } if (current2 != null && paused == false) { current2.add(s); } else if (paused) { - final CharSequence2 append = StartUtils.getPossibleAppend(s); + final StringLocated append = StartUtils.getPossibleAppend(s); if (append != null) { current2.add(append); } } - if (StartUtils.isArobaseUnpauseDiagram(s)) { + if (StartUtils.isArobaseUnpauseDiagram(s.getString())) { paused = false; reader2.setPaused(false); } - if (StartUtils.isArobaseEndDiagram(s) && current2 != null) { + if (StartUtils.isArobaseEndDiagram(s.getString()) && current2 != null) { if (paused) { current2.add(s); } - blocks.add(new BlockUml(current2, defines.cloneMe(), null)); + blocks.add(new BlockUml(current2, defines.cloneMe(), null, this)); current2 = null; reader2.setPaused(false); } @@ -132,7 +137,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer { return Collections.unmodifiableSet(usedFiles); } - public List getDefinition(String name) { + public List getDefinition(String name) { for (BlockUml block : blocks) { if (block.isStartDef(name)) { this.defines.importFrom(block.getLocalDefines()); @@ -142,4 +147,16 @@ public final class BlockUmlBuilder implements DefinitionsContainer { return Collections.emptyList(); } + public PreprocessorMode getPreprocessorMode() { + return mode; + } + + public void setPreprocessorMode(PreprocessorMode mode) { + this.mode = mode; + } + + public final ImportedFiles getImportedFiles() { + return importedFiles; + } + } diff --git a/src/net/sourceforge/plantuml/DefinitionsContainer.java b/src/net/sourceforge/plantuml/DefinitionsContainer.java index b84b2a627..5640191a8 100644 --- a/src/net/sourceforge/plantuml/DefinitionsContainer.java +++ b/src/net/sourceforge/plantuml/DefinitionsContainer.java @@ -37,8 +37,10 @@ package net.sourceforge.plantuml; import java.util.List; -public interface DefinitionsContainer { +import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; - public List getDefinition(String name); +public interface DefinitionsContainer extends PreprocessorModeSet { + + public List getDefinition(String name); } diff --git a/src/net/sourceforge/plantuml/EmbeddedDiagram.java b/src/net/sourceforge/plantuml/EmbeddedDiagram.java index 2af3b39c1..d6409ed2f 100644 --- a/src/net/sourceforge/plantuml/EmbeddedDiagram.java +++ b/src/net/sourceforge/plantuml/EmbeddedDiagram.java @@ -40,6 +40,7 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.List; import javax.imageio.ImageIO; @@ -84,6 +85,10 @@ public class EmbeddedDiagram implements CharSequence { private BufferedImage image; private final ISkinSimple skinParam; + public List splitInTwo(StringBounder stringBounder, double width) { + throw new UnsupportedOperationException(getClass().toString()); + } + private Draw(ISkinSimple skinParam) { this.skinParam = skinParam; } @@ -155,7 +160,7 @@ public class EmbeddedDiagram implements CharSequence { } private Diagram getSystem() throws IOException, InterruptedException { - final BlockUml blockUml = new BlockUml(system.as2(), Defines.createEmpty(), skinParam); + final BlockUml blockUml = new BlockUml(system.as2(), Defines.createEmpty(), skinParam, null); return blockUml.getDiagram(); } diff --git a/src/net/sourceforge/plantuml/FileFormatOption.java b/src/net/sourceforge/plantuml/FileFormatOption.java index b742d1988..ec629689c 100644 --- a/src/net/sourceforge/plantuml/FileFormatOption.java +++ b/src/net/sourceforge/plantuml/FileFormatOption.java @@ -47,7 +47,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; * @author Arnaud Roques * */ -public class FileFormatOption implements Serializable { +public final class FileFormatOption implements Serializable { private final FileFormat fileFormat; private final AffineTransform affineTransform; @@ -56,9 +56,14 @@ public class FileFormatOption implements Serializable { private final String svgLinkTarget; private final String hoverColor; private final TikzFontDistortion tikzFontDistortion; + private final double scale; + + public double getScaleCoef() { + return scale; + } public FileFormatOption(FileFormat fileFormat) { - this(fileFormat, null, true, false, "_top", false, null, TikzFontDistortion.getDefault()); + this(fileFormat, null, true, false, "_top", false, null, TikzFontDistortion.getDefault(), 1.0); } public StringBounder getDefaultStringBounder() { @@ -74,11 +79,12 @@ public class FileFormatOption implements Serializable { } public FileFormatOption(FileFormat fileFormat, boolean withMetadata) { - this(fileFormat, null, false, false, "_top", false, null, TikzFontDistortion.getDefault()); + this(fileFormat, null, false, false, "_top", false, null, TikzFontDistortion.getDefault(), 1.0); } private FileFormatOption(FileFormat fileFormat, AffineTransform at, boolean withMetadata, boolean useRedForError, - String svgLinkTarget, boolean debugsvek, String hoverColor, TikzFontDistortion tikzFontDistortion) { + String svgLinkTarget, boolean debugsvek, String hoverColor, TikzFontDistortion tikzFontDistortion, + double scale) { this.hoverColor = hoverColor; this.fileFormat = fileFormat; this.affineTransform = at; @@ -87,6 +93,7 @@ public class FileFormatOption implements Serializable { this.svgLinkTarget = svgLinkTarget; this.debugsvek = debugsvek; this.tikzFontDistortion = tikzFontDistortion; + this.scale = scale; if (tikzFontDistortion == null) { throw new IllegalArgumentException(); } @@ -94,22 +101,27 @@ public class FileFormatOption implements Serializable { public FileFormatOption withUseRedForError() { return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget, debugsvek, - hoverColor, tikzFontDistortion); + hoverColor, tikzFontDistortion, scale); } public FileFormatOption withTikzFontDistortion(TikzFontDistortion tikzFontDistortion) { return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget, debugsvek, - hoverColor, tikzFontDistortion); + hoverColor, tikzFontDistortion, scale); } public FileFormatOption withSvgLinkTarget(String svgLinkTarget) { return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, - debugsvek, hoverColor, tikzFontDistortion); + debugsvek, hoverColor, tikzFontDistortion, scale); } public FileFormatOption withHoverColor(String hoverColor) { return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, - debugsvek, hoverColor, tikzFontDistortion); + debugsvek, hoverColor, tikzFontDistortion, scale); + } + + public FileFormatOption withScale(double scale) { + return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, + debugsvek, hoverColor, tikzFontDistortion, scale); } @Override diff --git a/src/net/sourceforge/plantuml/FileUtils.java b/src/net/sourceforge/plantuml/FileUtils.java index d97f8bf1d..5bf2e72fd 100644 --- a/src/net/sourceforge/plantuml/FileUtils.java +++ b/src/net/sourceforge/plantuml/FileUtils.java @@ -152,7 +152,9 @@ public class FileUtils { // return ImageIO.read(f); // } - public static BufferedImage ImageIO_read(File f) { + // http://forum.plantuml.net/9048/img-tag-for-sequence-diagram-participants-does-always-render + + public synchronized static BufferedImage ImageIO_read(File f) { // https://www.experts-exchange.com/questions/26171948/Why-are-ImageIO-read-images-losing-their-transparency.html // https://stackoverflow.com/questions/18743790/can-java-load-images-with-transparency @@ -163,7 +165,7 @@ public class FileUtils { } } - public static BufferedImage ImageIO_read(URL url) { + public synchronized static BufferedImage ImageIO_read(URL url) { try { return readImage(new ImageIcon(url)); } catch (Exception e) { @@ -171,7 +173,7 @@ public class FileUtils { } } - private static BufferedImage readImage(final ImageIcon imageIcon) { + private synchronized static BufferedImage readImage(final ImageIcon imageIcon) { final Image tmpImage = imageIcon.getImage(); final BufferedImage image = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); diff --git a/src/net/sourceforge/plantuml/FontParam.java b/src/net/sourceforge/plantuml/FontParam.java index b83a0505a..99821476a 100644 --- a/src/net/sourceforge/plantuml/FontParam.java +++ b/src/net/sourceforge/plantuml/FontParam.java @@ -90,6 +90,7 @@ public enum FontParam { SEQUENCE_GROUP(11, Font.BOLD), // SEQUENCE_GROUP_HEADER(13, Font.BOLD), // PARTICIPANT(14, Font.PLAIN), // + PARTICIPANT_STEREOTYPE(14, Font.ITALIC), // SEQUENCE_TITLE(14, Font.BOLD), // STATE(14, Font.PLAIN), // STATE_ATTRIBUTE(12, Font.PLAIN), // diff --git a/src/net/sourceforge/plantuml/Guillemet.java b/src/net/sourceforge/plantuml/Guillemet.java new file mode 100644 index 000000000..c045eebc5 --- /dev/null +++ b/src/net/sourceforge/plantuml/Guillemet.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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; + +import java.util.StringTokenizer; +import java.util.regex.Matcher; + +public class Guillemet { + + public static final Guillemet NONE = new Guillemet("", ""); + public static final Guillemet DOUBLE_COMPARATOR = new Guillemet("<<", ">>"); + public static final Guillemet GUILLEMET = new Guillemet("\u00AB", "\u00BB"); + + private final String start; + private final String end; + + public Guillemet fromDescription(String value) { + if (value != null) { + if ("false".equalsIgnoreCase(value)) { + return Guillemet.DOUBLE_COMPARATOR; + } + if ("<< >>".equalsIgnoreCase(value)) { + return Guillemet.DOUBLE_COMPARATOR; + } + if ("none".equalsIgnoreCase(value)) { + return Guillemet.NONE; + } + if (value.contains(" ")) { + final StringTokenizer st = new StringTokenizer(value, " "); + return new Guillemet(st.nextToken(), st.nextToken()); + } + } + return Guillemet.GUILLEMET; + } + + private Guillemet(String start, String end) { + this.start = start; + this.end = end; + + } + + public String manageGuillemet(String st) { + if (this == DOUBLE_COMPARATOR) { + return st; + } + return st.replaceAll("\\<\\<\\s?((?:\\<&\\w+\\>|[^<>])+?)\\s?\\>\\>", Matcher.quoteReplacement(start) + "$1" + + Matcher.quoteReplacement(end)); + } + + public String manageGuillemetStrict(String st) { + if (this == DOUBLE_COMPARATOR) { + return st; + } + if (st.startsWith("<< ")) { + st = start + st.substring(3); + } else if (st.startsWith("<<")) { + st = start + st.substring(2); + } + if (st.endsWith(" >>")) { + st = st.substring(0, st.length() - 3) + end; + } else if (st.endsWith(">>")) { + st = st.substring(0, st.length() - 2) + end; + } + return st; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index 8a392e7c7..d09186bd2 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -125,7 +125,7 @@ public interface ISkinParam extends ISkinSimple { public int groupInheritance(); - public boolean useGuillemet(); + public Guillemet guillemet(); public boolean handwritten(); diff --git a/src/net/sourceforge/plantuml/LineLocationImpl.java b/src/net/sourceforge/plantuml/LineLocationImpl.java index 70dda4b7b..9fa9fbde4 100644 --- a/src/net/sourceforge/plantuml/LineLocationImpl.java +++ b/src/net/sourceforge/plantuml/LineLocationImpl.java @@ -64,8 +64,8 @@ public class LineLocationImpl implements LineLocation { } public static LineLocation fromLine(CharSequence cs) { - if (cs instanceof CharSequence2) { - return ((CharSequence2) cs).getLocation(); + if (cs instanceof StringLocated) { + return ((StringLocated) cs).getLocation(); } return null; } diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 72f1bb54e..3c2a2aa84 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -50,7 +50,6 @@ import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.creole.PSystemCreoleFactory; -import net.sourceforge.plantuml.cute.PSystemCuteFactory; import net.sourceforge.plantuml.dedication.PSystemDedicationFactory; import net.sourceforge.plantuml.definition.PSystemDefinitionFactory; import net.sourceforge.plantuml.descdiagram.DescriptionDiagramFactory; @@ -62,16 +61,12 @@ import net.sourceforge.plantuml.eggs.PSystemAppleTwoFactory; import net.sourceforge.plantuml.eggs.PSystemCharlieFactory; import net.sourceforge.plantuml.eggs.PSystemColorsFactory; import net.sourceforge.plantuml.eggs.PSystemEggFactory; -import net.sourceforge.plantuml.eggs.PSystemLostFactory; -import net.sourceforge.plantuml.eggs.PSystemPathFactory; import net.sourceforge.plantuml.eggs.PSystemRIPFactory; import net.sourceforge.plantuml.eggs.PSystemWelcomeFactory; import net.sourceforge.plantuml.flowdiagram.FlowDiagramFactory; import net.sourceforge.plantuml.font.PSystemListFontsFactory; import net.sourceforge.plantuml.help.HelpFactory; import net.sourceforge.plantuml.jcckit.PSystemJcckitFactory; -import net.sourceforge.plantuml.jungle.PSystemTreeFactory; -import net.sourceforge.plantuml.logo.PSystemLogoFactory; import net.sourceforge.plantuml.math.PSystemLatexFactory; import net.sourceforge.plantuml.math.PSystemMathFactory; import net.sourceforge.plantuml.mindmap.MindMapDiagramFactory; @@ -79,7 +74,6 @@ import net.sourceforge.plantuml.nwdiag.NwDiagramFactory; import net.sourceforge.plantuml.openiconic.PSystemListOpenIconicFactory; import net.sourceforge.plantuml.openiconic.PSystemOpenIconicFactory; import net.sourceforge.plantuml.oregon.PSystemOregonFactory; -import net.sourceforge.plantuml.postit.PostIdDiagramFactory; import net.sourceforge.plantuml.project3.GanttDiagramFactory; import net.sourceforge.plantuml.salt.PSystemSaltFactory; import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory; @@ -91,22 +85,23 @@ import net.sourceforge.plantuml.ugraphic.sprite.PSystemListInternalSpritesFactor import net.sourceforge.plantuml.version.License; import net.sourceforge.plantuml.version.PSystemLicenseFactory; import net.sourceforge.plantuml.version.PSystemVersionFactory; +import net.sourceforge.plantuml.wbs.WBSDiagramFactory; public class PSystemBuilder { public static final long startTime = System.currentTimeMillis(); - final public Diagram createPSystem(ISkinSimple skinParam, final List strings2) { + final public Diagram createPSystem(ISkinSimple skinParam, final List strings2) { final long now = System.currentTimeMillis(); Diagram result = null; try { - final DiagramType type = DiagramType.getTypeFromArobaseStart(strings2.get(0).toString2()); + final DiagramType type = DiagramType.getTypeFromArobaseStart(strings2.get(0).getString()); final UmlSource umlSource = new UmlSource(strings2, type == DiagramType.UML); // int cpt = 0; - for (CharSequence2 s : strings2) { + for (StringLocated s : strings2) { if (s.getPreprocessorError() != null) { Log.error("Preprocessor Error: " + s.getPreprocessorError()); final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, s.getPreprocessorError(), /* cpt */ @@ -153,10 +148,8 @@ public class PSystemBuilder { factories.add(new StateDiagramFactory()); factories.add(new ActivityDiagramFactory3()); factories.add(new CompositeDiagramFactory()); - // factories.add(new ObjectDiagramFactory()); factories.add(new BpmDiagramFactory(DiagramType.BPM)); - factories.add(new PostIdDiagramFactory()); - // factories.add(new PrintSkinFactory()); + // factories.add(new PostIdDiagramFactory()); factories.add(new PSystemLicenseFactory()); factories.add(new PSystemVersionFactory()); factories.add(new PSystemDonorsFactory()); @@ -171,12 +164,13 @@ public class PSystemBuilder { factories.add(new PSystemDotFactory(DiagramType.UML)); factories.add(new NwDiagramFactory()); factories.add(new MindMapDiagramFactory()); + factories.add(new WBSDiagramFactory()); + factories.add(new PSystemDitaaFactory(DiagramType.DITAA)); + factories.add(new PSystemDitaaFactory(DiagramType.UML)); if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) { - factories.add(new PSystemDitaaFactory(DiagramType.DITAA)); - factories.add(new PSystemDitaaFactory(DiagramType.UML)); factories.add(new PSystemJcckitFactory(DiagramType.JCCKIT)); factories.add(new PSystemJcckitFactory(DiagramType.UML)); - factories.add(new PSystemLogoFactory()); + // factories.add(new PSystemLogoFactory()); factories.add(new PSystemSudokuFactory()); } factories.add(new PSystemDefinitionFactory()); @@ -187,8 +181,8 @@ public class PSystemBuilder { factories.add(new PSystemEggFactory()); factories.add(new PSystemAppleTwoFactory()); factories.add(new PSystemRIPFactory()); - factories.add(new PSystemLostFactory()); - factories.add(new PSystemPathFactory()); + // factories.add(new PSystemLostFactory()); + // factories.add(new PSystemPathFactory()); factories.add(new PSystemOregonFactory()); factories.add(new PSystemCharlieFactory()); if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) { @@ -197,8 +191,8 @@ public class PSystemBuilder { factories.add(new GanttDiagramFactory(DiagramType.GANTT)); factories.add(new GanttDiagramFactory(DiagramType.UML)); factories.add(new FlowDiagramFactory()); - factories.add(new PSystemTreeFactory(DiagramType.JUNGLE)); - factories.add(new PSystemCuteFactory(DiagramType.CUTE)); + // factories.add(new PSystemTreeFactory(DiagramType.JUNGLE)); + // factories.add(new PSystemCuteFactory(DiagramType.CUTE)); factories.add(new PSystemDedicationFactory()); factories.add(new TimingDiagramFactory()); factories.add(new HelpFactory()); diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java index 8939fbb10..9d338f7a9 100644 --- a/src/net/sourceforge/plantuml/PSystemError.java +++ b/src/net/sourceforge/plantuml/PSystemError.java @@ -419,11 +419,13 @@ public class PSystemError extends AbstractPSystem { private List getPartialCode() { List result = new ArrayList(); - for (Iterator it = getSource().iterator2(); it.hasNext();) { - final CharSequence2 s = it.next(); - result.add(s.toString()); - if (s.getLocation().getDescription().equals(higherErrorPosition.getDescription()) - && s.getLocation().compareTo(higherErrorPosition) >= 0) { + 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; } } @@ -458,11 +460,7 @@ public class PSystemError extends AbstractPSystem { final String last = htmlStrings.get(idx); htmlStrings.set(idx, "" + last + ""); } - // final String errorLine = getSource().getLine(higherErrorPosition); - // final String err = StringUtils.hideComparatorCharacters(errorLine); - // if (StringUtils.isNotEmpty(err)) { - // htmlStrings.add("" + err + ""); - // } + final Collection textErrors = new LinkedHashSet(); for (ErrorUml er : printedErrors) { textErrors.add(er.getError()); diff --git a/src/net/sourceforge/plantuml/PSystemUtils.java b/src/net/sourceforge/plantuml/PSystemUtils.java index c0ad1c046..7f4e7968d 100644 --- a/src/net/sourceforge/plantuml/PSystemUtils.java +++ b/src/net/sourceforge/plantuml/PSystemUtils.java @@ -247,8 +247,8 @@ public class PSystemUtils { if (fileFormat.getFileFormat() == FileFormat.PNG) { result = new PngSplitter(suggestedFile, system.getHorizontalPages(), system.getVerticalPages(), - system.getMetadata(), system.getDpi(fileFormat), fileFormat.isWithMetadata(), system.getSkinParam() - .getSplitParam()).getFiles(); + system.getMetadata(), (int) (system.getScaleCoef(fileFormat) * 96), fileFormat.isWithMetadata(), + system.getSkinParam().getSplitParam()).getFiles(); } final List result2 = new ArrayList(); for (File f : result) { diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 91c7210c5..d0fe5fe8a 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -220,7 +220,7 @@ public class SkinParam implements ISkinParam { if (stereotype == null) { throw new IllegalArgumentException(); } - final String value2 = getValue("spotchar" + stereotype.getLabel(false)); + final String value2 = getValue("spotchar" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null && value2.length() > 0) { return value2.charAt(0); } @@ -230,7 +230,7 @@ public class SkinParam implements ISkinParam { public Colors getColors(ColorParam param, Stereotype stereotype) { if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getValue(param.name() + "color" + stereotype.getLabel(false)); + final String value2 = getValue(param.name() + "color" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null && getIHtmlColorSet().getColorIfValid(value2) != null) { return new Colors(value2, getIHtmlColorSet(), param.getColorType()); } @@ -261,7 +261,8 @@ public class SkinParam implements ISkinParam { private int getFontSize(Stereotype stereotype, FontParam... param) { if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getFirstValueNonNullWithSuffix("fontsize" + stereotype.getLabel(false), param); + final String value2 = getFirstValueNonNullWithSuffix( + "fontsize" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR), param); if (value2 != null && value2.matches("\\d+")) { return Integer.parseInt(value2); } @@ -279,7 +280,8 @@ public class SkinParam implements ISkinParam { private String getFontFamily(Stereotype stereotype, FontParam... param) { if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getFirstValueNonNullWithSuffix("fontname" + stereotype.getLabel(false), param); + final String value2 = getFirstValueNonNullWithSuffix( + "fontname" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR), param); if (value2 != null) { return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value2); } @@ -302,7 +304,8 @@ public class SkinParam implements ISkinParam { String value = null; if (stereotype != null) { checkStereotype(stereotype); - value = getFirstValueNonNullWithSuffix("fontcolor" + stereotype.getLabel(false), param); + value = getFirstValueNonNullWithSuffix("fontcolor" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR), + param); } if (value == null || getIHtmlColorSet().getColorIfValid(value) == null) { value = getFirstValueNonNullWithSuffix("fontcolor", param); @@ -330,7 +333,8 @@ public class SkinParam implements ISkinParam { String value = null; if (stereotype != null) { checkStereotype(stereotype); - value = getFirstValueNonNullWithSuffix("fontstyle" + stereotype.getLabel(false), param); + value = getFirstValueNonNullWithSuffix("fontstyle" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR), + param); } if (value == null) { value = getFirstValueNonNullWithSuffix("fontstyle", param); @@ -579,7 +583,7 @@ public class SkinParam implements ISkinParam { public boolean shadowing(Stereotype stereotype) { if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getValue("shadowing" + stereotype.getLabel(false)); + final String value2 = getValue("shadowing" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null) { return value2.equalsIgnoreCase("true"); } @@ -600,7 +604,7 @@ public class SkinParam implements ISkinParam { public boolean shadowingForNote(Stereotype stereotype) { if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getValue("note" + "shadowing" + stereotype.getLabel(false)); + final String value2 = getValue("note" + "shadowing" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null) { return value2.equalsIgnoreCase("true"); } @@ -619,7 +623,7 @@ public class SkinParam implements ISkinParam { final String name = skinParameter.getUpperCaseName(); if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getValue(name + "shadowing" + stereotype.getLabel(false)); + final String value2 = getValue(name + "shadowing" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null) { return value2.equalsIgnoreCase("true"); } @@ -743,7 +747,7 @@ public class SkinParam implements ISkinParam { private Double getCornerInternal(String key, CornerParam param, Stereotype stereotype) { if (stereotype != null) { - key += stereotype.getLabel(false); + key += stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR); } final String value = getValue(key); if (value != null && value.matches("\\d+")) { @@ -757,12 +761,14 @@ public class SkinParam implements ISkinParam { if (stereotype != null) { checkStereotype(stereotype); - final String styleValue = getValue(param.name() + "style" + stereotype.getLabel(false)); + final String styleValue = getValue(param.name() + "style" + + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (styleValue != null) { style = LinkStyle.fromString2(styleValue); } - final String value2 = getValue(param.name() + "thickness" + stereotype.getLabel(false)); + final String value2 = getValue(param.name() + "thickness" + + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null && value2.matches("[\\d.]+")) { if (style == null) { style = LinkStyle.NORMAL(); @@ -856,7 +862,7 @@ public class SkinParam implements ISkinParam { String value = getValue("activityshape"); if (stereotype != null) { checkStereotype(stereotype); - final String value2 = getValue("activityshape" + stereotype.getLabel(false)); + final String value2 = getValue("activityshape" + stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null) { value = value2; } @@ -896,12 +902,9 @@ public class SkinParam implements ISkinParam { return result; } - public boolean useGuillemet() { + public Guillemet guillemet() { final String value = getValue("guillemet"); - if ("false".equalsIgnoreCase(value)) { - return false; - } - return true; + return Guillemet.GUILLEMET.fromDescription(value); } public boolean handwritten() { diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java index 9ca92c204..9375473a1 100644 --- a/src/net/sourceforge/plantuml/SkinParamDelegator.java +++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java @@ -214,8 +214,8 @@ public class SkinParamDelegator implements ISkinParam { return skinParam.groupInheritance(); } - public boolean useGuillemet() { - return skinParam.useGuillemet(); + public Guillemet guillemet() { + return skinParam.guillemet(); } public boolean handwritten() { diff --git a/src/net/sourceforge/plantuml/SpriteContainer.java b/src/net/sourceforge/plantuml/SpriteContainer.java index 5374e4247..97b3c111d 100644 --- a/src/net/sourceforge/plantuml/SpriteContainer.java +++ b/src/net/sourceforge/plantuml/SpriteContainer.java @@ -41,6 +41,6 @@ public interface SpriteContainer { public Sprite getSprite(String name); - public boolean useGuillemet(); + public Guillemet guillemet(); } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/SpriteContainerEmpty.java b/src/net/sourceforge/plantuml/SpriteContainerEmpty.java index 5c9fb0edc..f131b72ef 100644 --- a/src/net/sourceforge/plantuml/SpriteContainerEmpty.java +++ b/src/net/sourceforge/plantuml/SpriteContainerEmpty.java @@ -59,8 +59,8 @@ public class SpriteContainerEmpty implements SpriteContainer, ISkinSimple { return 0; } - public boolean useGuillemet() { - return false; + public Guillemet guillemet() { + return Guillemet.DOUBLE_COMPARATOR; } public String getMonospacedFamily() { diff --git a/src/net/sourceforge/plantuml/CharSequence2Impl.java b/src/net/sourceforge/plantuml/StringLocated.java similarity index 58% rename from src/net/sourceforge/plantuml/CharSequence2Impl.java rename to src/net/sourceforge/plantuml/StringLocated.java index 34de42d50..ad60720be 100644 --- a/src/net/sourceforge/plantuml/CharSequence2Impl.java +++ b/src/net/sourceforge/plantuml/StringLocated.java @@ -35,17 +35,22 @@ */ package net.sourceforge.plantuml; -public class CharSequence2Impl implements CharSequence2 { +public class StringLocated { - private final CharSequence s; + private final String s; private final LineLocation location; - private String preprocessorError; + private final String preprocessorError; - public CharSequence2Impl(CharSequence s, LineLocation location) { + public StringLocated(String s, LineLocation location) { this(s, location, null); } - public CharSequence2Impl(CharSequence s, LineLocation location, String preprocessorError) { + @Override + public String toString() { + return super.toString() + " " + s; + } + + public StringLocated(String s, LineLocation location, String preprocessorError) { if (s == null) { throw new IllegalArgumentException(); } @@ -54,84 +59,59 @@ public class CharSequence2Impl implements CharSequence2 { this.preprocessorError = preprocessorError; } - // public static CharSequence2 errorPreprocessor(CharSequence s, String preprocessorError) { - // return new CharSequence2Impl("FOO4242", null, preprocessorError); - // } - - public CharSequence2 withErrorPreprocessor(String preprocessorError) { - return new CharSequence2Impl(s, location, preprocessorError); + public StringLocated withErrorPreprocessor(String preprocessorError) { + return new StringLocated(s, location, preprocessorError); } - public int length() { - return s.length(); + public StringLocated sub(int start, int end) { + return new StringLocated(this.getString().substring(start, end), this.getLocation(), + this.getPreprocessorError()); } - public char charAt(int index) { - return s.charAt(index); + public String getStringTrimmed() { + return StringUtils.trin(this.getString()); } - public CharSequence2 subSequence(int start, int end) { - return new CharSequence2Impl(s.subSequence(start, end), location, preprocessorError); - } - - public CharSequence toCharSequence() { - return s; - } - - @Override - public String toString() { - return s.toString(); - } - - public String toString2() { - return s.toString(); - } - - public LineLocation getLocation() { - return location; - } - - public CharSequence2 trin() { - return new CharSequence2Impl(StringUtils.trin(s.toString()), location, preprocessorError); - } - - public boolean startsWith(String start) { - return s.toString().startsWith(start); - } - - public String getPreprocessorError() { - return preprocessorError; - } - - public CharSequence2 removeInnerComment() { + public StringLocated removeInnerComment() { final String string = s.toString(); final String trim = string.replace('\t', ' ').trim(); if (trim.startsWith("/'")) { final int idx = string.indexOf("'/"); if (idx != -1) { - return new CharSequence2Impl(removeSpecialInnerComment(s.subSequence(idx + 2, s.length())), location, + return new StringLocated(removeSpecialInnerComment(s.substring(idx + 2, s.length())), location, preprocessorError); } } if (trim.endsWith("'/")) { final int idx = string.lastIndexOf("/'"); if (idx != -1) { - return new CharSequence2Impl(removeSpecialInnerComment(s.subSequence(0, idx)), location, - preprocessorError); + return new StringLocated(removeSpecialInnerComment(s.substring(0, idx)), location, preprocessorError); } } if (trim.contains("/'''") && trim.contains("'''/")) { - return new CharSequence2Impl(removeSpecialInnerComment(s), location, preprocessorError); + return new StringLocated(removeSpecialInnerComment(s), location, preprocessorError); } return this; } - private CharSequence removeSpecialInnerComment(CharSequence cs) { - final String s = cs.toString(); + private String removeSpecialInnerComment(String s) { if (s.contains("/'''") && s.contains("'''/")) { return s.replaceAll("/'''[-\\w]*'''/", ""); } - return cs; + return s; } + + public String getString() { + return s; + } + + public LineLocation getLocation() { + return location; + } + + public String getPreprocessorError() { + return preprocessorError; + } + } diff --git a/src/net/sourceforge/plantuml/StringUtils.java b/src/net/sourceforge/plantuml/StringUtils.java index ca43f7a17..24e0996e4 100644 --- a/src/net/sourceforge/plantuml/StringUtils.java +++ b/src/net/sourceforge/plantuml/StringUtils.java @@ -412,20 +412,6 @@ public class StringUtils { return s.endsWith("\\") && s.endsWith("\\\\") == false; } - public static String manageGuillemetStrict(String st) { - if (st.startsWith("<< ")) { - st = "\u00AB" + st.substring(3); - } else if (st.startsWith("<<")) { - st = "\u00AB" + st.substring(2); - } - if (st.endsWith(" >>")) { - st = st.substring(0, st.length() - 3) + "\u00BB"; - } else if (st.endsWith(">>")) { - st = st.substring(0, st.length() - 2) + "\u00BB"; - } - return st; - } - public static String rot(String s) { final StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { @@ -442,10 +428,6 @@ public class StringUtils { return sb.toString(); } - public static String manageGuillemet(String st) { - return st.replaceAll("\\<\\<\\s?((?:\\<&\\w+\\>|[^<>])+?)\\s?\\>\\>", "\u00AB$1\u00BB"); - } - public static String manageUnicodeNotationUplus(String s) { final Pattern pattern = Pattern.compile("\\"); final Matcher matcher = pattern.matcher(s); @@ -478,12 +460,15 @@ public class StringUtils { } public static String trinNoTrace(CharSequence s) { +// if (s instanceof CharSequence2) { +// return ((CharSequence2) s).getString().trim(); +// } return s.toString().trim(); } - public static String trin(CharSequence arg) { + public static String trin(String arg) { if (arg.length() == 0) { - return arg.toString(); + return arg; } int i = 0; while (i < arg.length() && isSpaceOrTabOrNull(arg.charAt(i))) { @@ -494,9 +479,9 @@ public class StringUtils { j--; } if (i == 0 && j == arg.length() - 1) { - return arg.toString(); + return arg; } - return arg.subSequence(i, j + 1).toString(); + return arg.substring(i, j + 1); } private static boolean isSpaceOrTabOrNull(char c) { diff --git a/src/net/sourceforge/plantuml/UmlDiagram.java b/src/net/sourceforge/plantuml/UmlDiagram.java index a846e1791..162dc51cc 100644 --- a/src/net/sourceforge/plantuml/UmlDiagram.java +++ b/src/net/sourceforge/plantuml/UmlDiagram.java @@ -207,16 +207,16 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann return animation; } - public final double getDpiFactor(FileFormatOption fileFormatOption) { + public final double getScaleCoef(FileFormatOption fileFormatOption) { if (getSkinParam().getDpi() == 96) { - return 1.0; + return fileFormatOption.getScaleCoef(); } - return getSkinParam().getDpi() / 96.0; + return getSkinParam().getDpi() * fileFormatOption.getScaleCoef() / 96.0; } - public final int getDpi(FileFormatOption fileFormatOption) { - return getSkinParam().getDpi(); - } + // public final int getDpi(FileFormatOption fileFormatOption) { + // return getSkinParam().getDpi(); + // } public final boolean isHideUnlinkedData() { return hideUnlinkedData; @@ -473,7 +473,7 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann if (f.exists() == false || f.canRead() == false) { return CommandExecutionResult.error("Cannot load skin from " + filename); } - final BlocLines lines = BlocLines.load(f); + final BlocLines lines = BlocLines.load(f, new LineLocationImpl(f.getName(), null)); final CommandSkinParam cmd1 = new CommandSkinParam(); final CommandSkinParamMultilines cmd2 = new CommandSkinParamMultilines(); for (int i = 0; i < lines.size(); i++) { diff --git a/src/net/sourceforge/plantuml/UmlDiagramType.java b/src/net/sourceforge/plantuml/UmlDiagramType.java index 048ada7ff..d2a1d76f3 100644 --- a/src/net/sourceforge/plantuml/UmlDiagramType.java +++ b/src/net/sourceforge/plantuml/UmlDiagramType.java @@ -36,5 +36,5 @@ package net.sourceforge.plantuml; public enum UmlDiagramType { - SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, HELP + SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, HELP } diff --git a/src/net/sourceforge/plantuml/acearth/PSystemXearth.java b/src/net/sourceforge/plantuml/acearth/PSystemXearth.java index eba02c869..f3534d866 100644 --- a/src/net/sourceforge/plantuml/acearth/PSystemXearth.java +++ b/src/net/sourceforge/plantuml/acearth/PSystemXearth.java @@ -52,7 +52,6 @@ import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; - import ext.plantuml.com.ctreber.acearth.ACearth; import ext.plantuml.com.ctreber.acearth.ConfigurationACearth; import ext.plantuml.com.ctreber.acearth.plugins.markers.Marker; diff --git a/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java b/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java index 7304c8c2b..c41096ad8 100644 --- a/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java +++ b/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java @@ -44,7 +44,6 @@ import net.sourceforge.plantuml.command.PSystemBasicFactory; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; - import ext.plantuml.com.ctreber.acearth.plugins.markers.Marker; public class PSystemXearthFactory extends PSystemBasicFactory { diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java index 60d83ba89..5acadb3ba 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.activitydiagram.command; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -78,7 +79,7 @@ public class CommandIf extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram system, LineLocation location, RegexResult arg) { final IEntity entity1 = CommandLinkActivity.getEntity(system, arg, true); if (entity1 == null) { return CommandExecutionResult.error("No if possible at this point"); diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java index 2bacf37d9..83b331c6e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.activitydiagram.command; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -111,7 +112,7 @@ public class CommandLinkActivity extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram diagram, LineLocation location, RegexResult arg) { final IEntity entity1 = getEntity(diagram, arg, true); if (entity1 == null) { return CommandExecutionResult.error("No such activity"); diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java index e61b66a54..041cb0ad8 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java @@ -39,6 +39,7 @@ import java.util.List; import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -110,7 +111,7 @@ public class CommandLinkLongActivity extends CommandMultilines2 protected CommandExecutionResult executeNow(final ActivityDiagram diagram, BlocLines lines) { lines = lines.trim(false); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); final IEntity entity1 = CommandLinkActivity.getEntity(diagram, line0, true); if (entity1 == null) { @@ -129,14 +130,14 @@ public class CommandLinkLongActivity extends CommandMultilines2 final String desc0 = line0.get("DESC", 0); Url urlActivity = null; if (StringUtils.isNotEmpty(desc0)) { - urlActivity = extractUrl(diagram, desc0); + urlActivity = extractUrlString(diagram, desc0); if (urlActivity == null) { sb.append(desc0); sb.append(BackSlash.BS_BS_N); } } int i = 0; - for (CharSequence cs : lines.subExtract(1, 1)) { + for (StringLocated cs : lines.subExtract(1, 1)) { i++; if (i == 1 && urlActivity == null) { urlActivity = extractUrl(diagram, cs); @@ -144,14 +145,14 @@ public class CommandLinkLongActivity extends CommandMultilines2 continue; } } - sb.append(cs); + sb.append(cs.getString()); if (i < lines.size() - 2) { sb.append(BackSlash.BS_BS_N); } } final List lineLast = StringUtils.getSplit(MyPattern.cmpile(getPatternEnd()), lines.getLast499() - .toString()); + .getString()); if (StringUtils.isNotEmpty(lineLast.get(0))) { if (sb.length() > 0 && sb.toString().endsWith(BackSlash.BS_BS_N) == false) { sb.append(BackSlash.BS_BS_N); @@ -223,9 +224,13 @@ public class CommandLinkLongActivity extends CommandMultilines2 return CommandExecutionResult.ok(); } - public Url extractUrl(final ActivityDiagram diagram, CharSequence string) { + public Url extractUrl(final ActivityDiagram diagram, StringLocated string) { + return extractUrlString(diagram, string.getString()); + } + + public Url extractUrlString(final ActivityDiagram diagram, String string) { final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), ModeUrl.STRICT); - return urlBuilder.getUrl(string.toString()); + return urlBuilder.getUrl(string); } } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java index 45ae5d515..16a80b577 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -77,7 +78,7 @@ public class CommandPartition extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram diagram, LineLocation location, RegexResult arg) { final Code code = Code.of(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("NAME", 0))); final IGroup currentPackage = diagram.getCurrentGroup(); diagram.gotoGroup2(code, Display.getWithNewlines(code), GroupType.PACKAGE, currentPackage, diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java index 276f4ce6e..207dabf04 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -171,7 +171,11 @@ public class ActivityDiagram3 extends UmlDiagram { if (last instanceof InstructionWhile == false) { return false; } - ((InstructionWhile) last).setSpecial(special); + final InstructionWhile instructionWhile = (InstructionWhile) last; + if (instructionWhile.containsBreak()) { + return false; + } + instructionWhile.setSpecial(special); return true; } @@ -220,7 +224,7 @@ public class ActivityDiagram3 extends UmlDiagram { final double dpiFactor; final Scale scale = getScale(); if (scale == null) { - dpiFactor = getDpiFactor(fileFormatOption); + dpiFactor = getScaleCoef(fileFormatOption); } else { dpiFactor = scale.getScale(dim.getWidth(), dim.getHeight()); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/Branch.java b/src/net/sourceforge/plantuml/activitydiagram3/Branch.java index 147119ea9..524c7b797 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/Branch.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/Branch.java @@ -60,6 +60,10 @@ public class Branch { private Ftile ftile; + public boolean containsBreak() { + return list.containsBreak(); + } + public Branch(Swimlane swimlane, Display labelPositive, Display labelTest, HtmlColor color, Display inlabel) { if (labelPositive == null) { throw new IllegalArgumentException(); @@ -162,4 +166,5 @@ public class Branch { return special; } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/Instruction.java b/src/net/sourceforge/plantuml/activitydiagram3/Instruction.java index 379c3ccaa..c3f3055a4 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/Instruction.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/Instruction.java @@ -55,5 +55,7 @@ public interface Instruction extends Swimable { public LinkRendering getInLinkRendering(); public boolean addNote(Display note, NotePosition position, NoteType type, Colors colors, Swimlane swimlaneNote); + + public boolean containsBreak(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionBreak.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionBreak.java index 25489fd71..aea96d2d7 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionBreak.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionBreak.java @@ -68,4 +68,8 @@ public class InstructionBreak extends MonoSwimable implements Instruction { return inlinkRendering; } + public boolean containsBreak() { + return true; + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionEnd.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionEnd.java index 73aa34557..94044e6a3 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionEnd.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionEnd.java @@ -69,4 +69,8 @@ public class InstructionEnd extends MonoSwimable implements Instruction { return inlinkRendering; } + public boolean containsBreak() { + return false; + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionFork.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionFork.java index d6b993879..667885667 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionFork.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionFork.java @@ -59,6 +59,15 @@ public class InstructionFork extends WithNote implements Instruction { private String label; boolean finished = false; + public boolean containsBreak() { + for (InstructionList fork : forks) { + if (fork.containsBreak()) { + return true; + } + } + return false; + } + public InstructionFork(Instruction parent, LinkRendering inlinkRendering, ISkinParam skinParam) { this.parent = parent; this.inlinkRendering = inlinkRendering; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionGoto.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionGoto.java index d82968c67..2a99e0c8b 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionGoto.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionGoto.java @@ -65,4 +65,8 @@ public class InstructionGoto extends MonoSwimable implements Instruction { return LinkRendering.none(); } + public boolean containsBreak() { + return false; + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionGroup.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionGroup.java index 3d37379bc..4fe8d574e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionGroup.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionGroup.java @@ -63,6 +63,10 @@ public class InstructionGroup implements Instruction, InstructionCollection { private final double roundCorner; private PositionedNote note = null; + public boolean containsBreak() { + return list.containsBreak(); + } + public InstructionGroup(Instruction parent, Display test, HtmlColor backColor, HtmlColor titleColor, Swimlane swimlane, HtmlColor borderColor, LinkRendering linkRendering, USymbol type, double roundCorner) { this.list = new InstructionList(swimlane); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java index 3d63aef51..67cb1c66e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java @@ -69,6 +69,18 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC private final Swimlane swimlane; + public boolean containsBreak() { + for (Branch branch : thens) { + if (branch.containsBreak()) { + return true; + } + } + if (elseBranch != null) { + return elseBranch.containsBreak(); + } + return false; + } + public InstructionIf(Swimlane swimlane, Instruction parent, Display labelTest, Display whenThen, LinkRendering inlinkRendering, HtmlColor color, ISkinParam skinParam) { this.parent = parent; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionLabel.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionLabel.java index 71fc0807b..9e89802f6 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionLabel.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionLabel.java @@ -65,4 +65,8 @@ public class InstructionLabel extends MonoSwimable implements Instruction { return LinkRendering.none(); } + public boolean containsBreak() { + return false; + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java index a8221a96f..e911a1c89 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java @@ -57,6 +57,15 @@ public class InstructionList extends WithNote implements Instruction, Instructio private final List all = new ArrayList(); private final Swimlane defaultSwimlane; + public boolean containsBreak() { + for (Instruction ins : all) { + if (ins.containsBreak()) { + return true; + } + } + return false; + } + public InstructionList() { this(null); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionPartition.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionPartition.java index 45ec44aa5..9d3917a1a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionPartition.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionPartition.java @@ -90,4 +90,8 @@ public class InstructionPartition implements Instruction { throw new UnsupportedOperationException(); } + public boolean containsBreak() { + return list.containsBreak(); + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java index 919e15b96..ff2a18dd7 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java @@ -65,6 +65,11 @@ public class InstructionRepeat implements Instruction { private boolean testCalled = false; private LinkRendering endRepeatLinkRendering = LinkRendering.none(); private LinkRendering backRepeatLinkRendering = LinkRendering.none(); + + public boolean containsBreak() { + return repeatList.containsBreak(); + } + public InstructionRepeat(Swimlane swimlane, Instruction parent, LinkRendering nextLinkRenderer, HtmlColor color, Display startLabel) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java index e36396769..475d97662 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java @@ -52,6 +52,11 @@ public class InstructionSimple extends MonoSwimable implements Instruction { private final LinkRendering inlinkRendering; private final BoxStyle style; private final Url url; + + public boolean containsBreak() { + return false; + } + public InstructionSimple(Display label, LinkRendering inlinkRendering, Swimlane swimlane, BoxStyle style, Url url, Colors colors) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java index 06b62128b..c311885d3 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSplit.java @@ -61,6 +61,16 @@ public class InstructionSplit implements Instruction { throw new IllegalArgumentException(); } } + + public boolean containsBreak() { + for (InstructionList split : splits) { + if (split.containsBreak()) { + return true; + } + } + return false; + } + private InstructionList getLast() { return splits.get(splits.size() - 1); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSpot.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSpot.java index cc00e7c4b..d1d8a9e9a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSpot.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSpot.java @@ -46,6 +46,10 @@ public class InstructionSpot extends MonoSwimable implements Instruction { private final LinkRendering inlinkRendering; private final String spot; + public boolean containsBreak() { + return false; + } + public InstructionSpot(String spot, LinkRendering inlinkRendering, Swimlane swimlane) { super(swimlane); this.spot = spot; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionStart.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionStart.java index e91a56f32..ed327e1ed 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionStart.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionStart.java @@ -50,6 +50,11 @@ public class InstructionStart extends MonoSwimable implements Instruction { throw new IllegalArgumentException(); } } + + public boolean containsBreak() { + return false; + } + public Ftile createFtile(FtileFactory factory) { Ftile result = factory.start(getSwimlaneIn()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionStop.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionStop.java index 5a02a299b..f44cf9b46 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionStop.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionStop.java @@ -50,6 +50,11 @@ public class InstructionStop extends MonoSwimable implements Instruction { throw new IllegalArgumentException(); } } + + public boolean containsBreak() { + return false; + } + public Ftile createFtile(FtileFactory factory) { Ftile result = factory.stop(getSwimlaneIn()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java index ce4b6337c..ca3ecb52f 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java @@ -166,4 +166,8 @@ public class InstructionWhile extends WithNote implements Instruction, Instructi this.specialOut = special; } + public boolean containsBreak() { + return repeatList.containsBreak(); + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java index 1d49aa0d0..da784205e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -74,7 +75,7 @@ public class CommandActivity3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final Url url; if (arg.get("URL", 0) == null) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLegacy1.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLegacy1.java index 27b282e35..a39fa2c00 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLegacy1.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLegacy1.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -59,7 +60,7 @@ public class CommandActivityLegacy1 extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.addActivity(Display.getWithNewlines(arg.get("LABEL", 0)), BoxStyle.PLAIN, null, Colors.empty()); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java index 821beed95..62fb98ea3 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; import net.sourceforge.plantuml.command.BlocLines; @@ -74,7 +73,7 @@ public class CommandActivityLong3 extends CommandMultilines2 { protected CommandExecutionResult executeNow(ActivityDiagram3 diagram, BlocLines lines) { lines = lines.removeEmptyColumns(); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); final Colors colors = color().getColor(line0, diagram.getSkinParam().getIHtmlColorSet()); // final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0)); final BoxStyle style = BoxStyle.fromChar(lines.getLastChar()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java index 57afd3168..d9d9217fb 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -65,7 +66,7 @@ public class CommandArrow3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final String colorString = arg.get("COLOR", 0); if (colorString != null) { diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java index 499575598..3d9649192 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml.activitydiagram3.command; import java.util.List; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -73,7 +72,7 @@ public class CommandArrowLong3 extends CommandMultilines2 { protected CommandExecutionResult executeNow(ActivityDiagram3 diagram, BlocLines lines) { lines = lines.removeEmptyColumns(); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); // final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0)); // diagram.setColorNextArrow(HtmlColorAndStyle.fromColor(color)); final String colorString = line0.get("COLOR", 0); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java index 176b889b1..434e5bdfa 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackward3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -59,7 +60,7 @@ public class CommandBackward3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final Display label = Display.getWithNewlines(arg.get("LABEL", 0)); return diagram.backwardWhile(label); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBreak.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBreak.java index 25e6b03e2..c09744f93 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBreak.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBreak.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandBreak extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.breakInstruction(); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCircleSpot3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCircleSpot3.java index 3be48aecc..38a8fb88c 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCircleSpot3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandCircleSpot3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandCircleSpot3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.addSpot(arg.get("SPOT", 0)); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElse3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElse3.java index e3aae24df..6cedc53d2 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElse3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElse3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -58,7 +59,7 @@ public class CommandElse3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { // if (getSystem().getLastEntityConsulted() == null) { // return CommandExecutionResult.error("No if for this endif"); // } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf2.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf2.java index f020fe232..9f1415296 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf2.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseIf2.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -66,7 +67,7 @@ public class CommandElseIf2 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); String test = arg.get("TEST", 0); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseLegacy1.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseLegacy1.java index ee965266a..fe14df79c 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseLegacy1.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandElseLegacy1.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -58,7 +59,7 @@ public class CommandElseLegacy1 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { // if (getSystem().getLastEntityConsulted() == null) { // return CommandExecutionResult.error("No if for this endif"); // } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEnd3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEnd3.java index de99c07f5..c52410dba 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEnd3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEnd3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandEnd3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.end(); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEndif3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEndif3.java index 0e5145ebd..7453363a5 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEndif3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandEndif3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandEndif3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { // if (getSystem().getLastEntityConsulted() == null) { // return CommandExecutionResult.error("No if for this endif"); // } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandFork3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandFork3.java index c8829793c..7b2c3e0bc 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandFork3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandFork3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandFork3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.fork(); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkAgain3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkAgain3.java index daba7bdf9..25d180806 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkAgain3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkAgain3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandForkAgain3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { return diagram.forkAgain(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkEnd3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkEnd3.java index f30329b1e..9f818abd8 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkEnd3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandForkEnd3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.activitydiagram3.ForkStyle; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -59,7 +60,7 @@ public class CommandForkEnd3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final String style = arg.get("STYLE", 0); final ForkStyle forkStyle = style.contains("merge") ? ForkStyle.MERGE : ForkStyle.FORK; final String label = arg.get("LABEL", 0); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGoto.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGoto.java index 86bd5f2f6..97e8f3253 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGoto.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGoto.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -58,7 +59,7 @@ public class CommandGoto extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final String name = arg.get("NAME", 0); return diagram.addGoto(name); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroup3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroup3.java index 7ae135752..ae1c5dfce 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroup3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroup3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -59,7 +60,7 @@ public class CommandGroup3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.startGroup(Display.getWithNewlines(arg.get("NAME", 0)), null, null, null, USymbol.FRAME, 0); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroupEnd3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroupEnd3.java index 0992eaf36..d40b1194e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroupEnd3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandGroupEnd3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -55,7 +56,7 @@ public class CommandGroupEnd3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { return diagram.endGroup(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java index 7cd9d34f8..932b12089 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -63,7 +64,7 @@ public class CommandIf2 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); String test = arg.get("TEST", 0); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java index abcb41780..348bf0cfb 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -64,7 +65,7 @@ public class CommandIf4 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); String test = arg.get("TEST", 0); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java index fb11c1d1f..ddf24a2a2 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -60,7 +61,7 @@ public class CommandIfLegacy1 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.startIf(Display.getWithNewlines(arg.get("TEST", 0)), Display.getWithNewlines(arg.get("WHEN", 0)), null); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandKill3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandKill3.java index 2a8ea7dbc..caeca28dc 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandKill3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandKill3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandKill3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { return diagram.kill(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLabel.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLabel.java index 7bc11a08d..0f9696bb9 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLabel.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLabel.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -58,7 +59,7 @@ public class CommandLabel extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final String name = arg.get("NAME", 0); return diagram.addLabel(name); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLink3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLink3.java index 4553bffe2..bddc6147f 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLink3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandLink3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -59,7 +60,7 @@ public class CommandLink3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); if (color != null) { diagram.setColorNextArrow(HtmlColorAndStyle.fromColor(color)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNolink.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNolink.java index 1e3c68062..584f92f83 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNolink.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNolink.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -57,7 +58,7 @@ public class CommandNolink extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { // diagram.setColorNextArrow(color); diagram.setLabelNextArrow(Display.getWithNewlines("NOLINK")); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNote3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNote3.java index e1f4f8519..35f9e06da 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNote3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNote3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -71,7 +72,7 @@ public class CommandNote3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet()); final Display note = Display.getWithNewlines(arg.get("NOTE", 0)); final NotePosition position = NotePosition.defaultLeft(arg.get("POSITION", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java index 585a5b856..ccc8cd094 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -68,7 +67,7 @@ public class CommandNoteLong3 extends CommandMultilines2 { protected CommandExecutionResult executeNow(final ActivityDiagram3 diagram, BlocLines lines) { // final List in = StringUtils.removeEmptyColumns2(lines.subList(1, lines.size() - 1)); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); final NotePosition position = NotePosition.defaultLeft(line0.get("POSITION", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java index 1204d7c90..bb6289686 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.activitydiagram3.command; import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -110,7 +111,7 @@ public class CommandPartition3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final String partitionTitle = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("NAME", 0)); final String b1 = arg.get("BACK1", 0); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java index f1ad475ec..0bb76c32d 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -61,7 +62,7 @@ public class CommandRepeat3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); final Display label = Display.getWithNewlines(arg.get("LABEL", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3.java index dbcba288b..53f37fe99 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -87,7 +88,7 @@ public class CommandRepeatWhile3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final Display test = Display.getWithNewlines(arg.getLazzy("TEST", 0)); final Display yes = Display.getWithNewlines(arg.getLazzy("WHEN", 0)); final Display out = Display.getWithNewlines(arg.getLazzy("OUT", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java index c1f0eab3b..70bf3a596 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.activitydiagram3.command; import java.util.List; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.BlocLines; @@ -76,8 +77,8 @@ public class CommandRepeatWhile3Multilines extends CommandMultilines3 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.split(); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitAgain3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitAgain3.java index ba6a48fe8..af76eb168 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitAgain3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitAgain3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandSplitAgain3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { return diagram.splitAgain(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitEnd3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitEnd3.java index c4cf8493c..44bfc09a7 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitEnd3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSplitEnd3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandSplitEnd3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { return diagram.endSplit(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStart3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStart3.java index a2e36bdfe..eeaf29a34 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStart3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStart3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandStart3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { // if (getSystem().getLastEntityConsulted() == null) { // return CommandExecutionResult.error("No if for this endif"); // } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStop3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStop3.java index 65c5259ac..7f8c33a3d 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStop3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandStop3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandStop3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { diagram.stop(); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane.java index f64fc463e..9bfb2c1ff 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -62,7 +63,7 @@ public class CommandSwimlane extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); final String name = arg.get("SWIMLANE", 0); final Display label = Display.getWithNewlines(arg.get("LABEL", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane2.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane2.java index 12f3a2eb7..289f71edb 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane2.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandSwimlane2.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -62,7 +63,7 @@ public class CommandSwimlane2 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); final String name = arg.get("SWIMLANE", 0); final Display label = Display.getWithNewlines(arg.get("LABEL", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhile3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhile3.java index 7b39a0ff1..ab454f1b5 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhile3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhile3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -65,7 +66,7 @@ public class CommandWhile3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); diagram.doWhile(Display.getWithNewlines(arg.get("TEST", 0)), Display.getWithNewlines(arg.get("YES", 0)), color); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhileEnd3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhileEnd3.java index 24fb81e56..e021634ba 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhileEnd3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandWhileEnd3.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -57,7 +58,7 @@ public class CommandWhileEnd3 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { return diagram.endwhile(Display.getWithNewlines(arg.get("OUT", 0))); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileKilled.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileKilled.java index ab1b357da..bd8391a61 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileKilled.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileKilled.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.activitydiagram3.ftile; +import java.util.Collection; import java.util.Set; import net.sourceforge.plantuml.graphic.StringBounder; @@ -48,6 +49,11 @@ public class FtileKilled extends AbstractFtile { super(tileToKill.skinParam()); this.tile = tileToKill; } + + @Override + public Collection getMyChildren() { + return tile.getMyChildren(); + } public Set getSwimlanes() { return tile.getSwimlanes(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesA.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesA.java index acbcc072c..78d23dc50 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesA.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesA.java @@ -39,7 +39,6 @@ import java.awt.geom.Dimension2D; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.activitydiagram3.Instruction; @@ -57,8 +56,6 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.UGraphicIntercep import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.VCompactFactory; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.AbstractTextBlock; -import net.sourceforge.plantuml.graphic.FontConfiguration; -import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java index 87b8bae24..537a0929a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact; -import java.awt.geom.Dimension2D; import java.util.List; import net.sourceforge.plantuml.ColorParam; @@ -97,27 +96,29 @@ public class FtileFactoryDelegatorWhile extends FtileFactoryDelegator { final Genealogy genealogy = new Genealogy(result); - final FtileBreak ftileBreak = (FtileBreak) weldingPoints.get(0); + for (WeldingPoint w : weldingPoints) { + final FtileBreak ftileBreak = (FtileBreak) w; + result = FtileUtils.addConnection(result, new Connection() { + public void drawU(UGraphic ug) { + final UTranslate tr1 = genealogy.getTranslate(ftileBreak, ug.getStringBounder()); - result = FtileUtils.addConnection(result, new Connection() { - public void drawU(UGraphic ug) { - final UTranslate tr1 = genealogy.getTranslate(ftileBreak, ug.getStringBounder()); + final Snake snake = new Snake(getFtile1().arrowHorizontalAlignment(), arrowColor, Arrows + .asToLeft()); + snake.addPoint(tr1.getDx(), tr1.getDy()); + snake.addPoint(Diamond.diamondHalfSize, tr1.getDy()); + ug.draw(snake); + } - final Snake snake = new Snake(getFtile1().arrowHorizontalAlignment(), arrowColor, Arrows.asToLeft()); - snake.addPoint(tr1.getDx(), tr1.getDy()); - snake.addPoint(Diamond.diamondHalfSize, tr1.getDy()); - ug.draw(snake); - } + public Ftile getFtile1() { + return ftileBreak; + } - public Ftile getFtile1() { - return ftileBreak; - } + public Ftile getFtile2() { + return null; + } - public Ftile getFtile2() { - return null; - } - - }); + }); + } } return result; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java index f349f6a04..7a64521c2 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfLongHorizontal.java @@ -162,7 +162,8 @@ class FtileIfLongHorizontal extends AbstractFtile { final TextBlock tb1 = branch.getLabelPositive().create(fcArrow, HorizontalAlignment.LEFT, ftileFactory.skinParam()); final TextBlock tbTest = branch.getLabelTest().create(fcTest, - ftileFactory.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT), ftileFactory.skinParam()); + ftileFactory.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT), + ftileFactory.skinParam()); final HtmlColor diamondColor = branch.getColor() == null ? backColor : branch.getColor(); FtileDiamondInside2 diamond = new FtileDiamondInside2(branch.skinParam(), diamondColor, borderColor, @@ -189,12 +190,18 @@ class FtileIfLongHorizontal extends AbstractFtile { final FtileIfLongHorizontal result = new FtileIfLongHorizontal(diamonds, inlabelSizes, tiles, tile2, arrowColor); final List conns = new ArrayList(); + int nbOut = 0; + for (int i = 0; i < thens.size(); i++) { final Ftile ftile = tiles.get(i); final Ftile diam = diamonds.get(i); final Rainbow rainbowIn = FtileIfWithLinks.getInColor(thens.get(i), arrowColor); final Branch branch = thens.get(i); + + if (branch.getFtile().calculateDimension(ftileFactory.getStringBounder()).hasPointOut()) { + nbOut++; + } final Rainbow rainbowOut = branch.getInlinkRenderingColorAndStyle(); TextBlock out2 = null; if (branch.getSpecial() != null) { @@ -218,10 +225,12 @@ class FtileIfLongHorizontal extends AbstractFtile { } conns.add(result.new ConnectionLastElseIn(FtileIfWithLinks.getInColor(branch2, arrowColor))); - conns.add(result.new ConnectionLastElseOut(arrowColor, out2)); - final Rainbow horizontalOutColor = afterEndwhile.getRainbow(arrowColor); - conns.add(result.new ConnectionHline(horizontalOutColor)); - // conns.add(result.new ConnectionHline(HtmlColorUtils.BLUE)); + conns.add(result.new ConnectionLastElseOut(arrowColor, out2, nbOut)); + final boolean horizontalOut = nbOut > 0; + if (horizontalOut) { + final Rainbow horizontalOutColor = afterEndwhile.getRainbow(arrowColor); + conns.add(result.new ConnectionHline(horizontalOutColor)); + } return FtileUtils.addConnection(result, conns); } @@ -329,11 +338,13 @@ class FtileIfLongHorizontal extends AbstractFtile { private final Rainbow arrowColor; private final TextBlock out2; + private final int nbOut; - public ConnectionLastElseOut(Rainbow arrowColor, TextBlock out2) { + public ConnectionLastElseOut(Rainbow arrowColor, TextBlock out2, int nbOut) { super(tile2, null); this.arrowColor = arrowColor; this.out2 = out2; + this.nbOut = nbOut; } public void drawU(UGraphic ug) { @@ -344,13 +355,17 @@ class FtileIfLongHorizontal extends AbstractFtile { return; } final Point2D p1 = tr1.getTranslated(dim.getPointOut()); - final double totalHeight = calculateDimensionInternal(stringBounder).getHeight(); + final FtileGeometry full = calculateDimensionInternal(stringBounder); + final double totalHeight = full.getHeight(); final Point2D p2 = new Point2D.Double(p1.getX(), totalHeight); final Snake snake = new Snake(arrowHorizontalAlignment(), arrowColor, Arrows.asToDown()); snake.setLabel(out2); snake.addPoint(p1); snake.addPoint(p2); + if (nbOut == 0) { + snake.addPoint(new Point2D.Double(full.getLeft(), totalHeight)); + } ug.draw(snake); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java index dfc5c8da7..259887521 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java @@ -44,7 +44,6 @@ import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; -import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.activitydiagram3.LinkRendering; import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractFtile; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileCircleStop.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileCircleStop.java index 832692eb9..a60e3ae7f 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileCircleStop.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileCircleStop.java @@ -45,6 +45,8 @@ 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.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlColorMiddle; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -54,7 +56,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class FtileCircleStop extends AbstractFtile { - private static final int SIZE = 20; + private static final int SIZE = 22; private final HtmlColor backColor; private final Swimlane swimlane; @@ -86,26 +88,19 @@ public class FtileCircleStop extends AbstractFtile { } public void drawU(UGraphic ug) { - double xTheoricalPosition = 0; - double yTheoricalPosition = 0; - xTheoricalPosition = Math.round(xTheoricalPosition); - yTheoricalPosition = Math.round(yTheoricalPosition); - final UEllipse circle = new UEllipse(SIZE, SIZE); if (skinParam().shadowing(null)) { circle.setDeltaShadow(3); } - ug.apply(new UChangeColor(backColor)).apply(new UChangeBackColor(null)) - .apply(new UTranslate(xTheoricalPosition, yTheoricalPosition)).draw(circle); + ug.apply(new UChangeColor(backColor)).apply(new UChangeBackColor(HtmlColorUtils.WHITE)).draw(circle); - final double delta = 4; + final double delta = 5; final UEllipse circleSmall = new UEllipse(SIZE - delta * 2, SIZE - delta * 2); - if (skinParam().shadowing(null)) { - circleSmall.setDeltaShadow(3); - } - ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(backColor)) - .apply(new UTranslate(xTheoricalPosition + delta + .5, yTheoricalPosition + delta + .5)) - .draw(circleSmall); + // if (skinParam().shadowing(null)) { + // circleSmall.setDeltaShadow(3); + // } + ug.apply(new UChangeColor(new HtmlColorMiddle(backColor, HtmlColorUtils.WHITE))) + .apply(new UChangeBackColor(backColor)).apply(new UTranslate(delta, delta)).draw(circleSmall); } @Override diff --git a/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java b/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java index e2a47545e..0f75f491e 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java +++ b/src/net/sourceforge/plantuml/bpm/CommandDockedEvent.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandDockedEvent extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { final String label = arg.get("LABEL", 0); final BpmElement element = new BpmElement(null, BpmElementType.DOCKED_EVENT, label); diff --git a/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java b/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java index c6c19b8ab..dbdc9ea3d 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java +++ b/src/net/sourceforge/plantuml/bpm/CommandElseBranch.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandElseBranch extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { return diagram.elseBranch(); } diff --git a/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java b/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java index ce0d11588..42543dc70 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java +++ b/src/net/sourceforge/plantuml/bpm/CommandEndBranch.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandEndBranch extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { return diagram.endBranch(); } diff --git a/src/net/sourceforge/plantuml/bpm/CommandGoto.java b/src/net/sourceforge/plantuml/bpm/CommandGoto.java index 543dbc37b..b2395a0ec 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandGoto.java +++ b/src/net/sourceforge/plantuml/bpm/CommandGoto.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandGoto extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { final BpmEvent event = new BpmEventGoto(arg.get("ID", 0)); return diagram.addEvent(event); } diff --git a/src/net/sourceforge/plantuml/bpm/CommandMerge.java b/src/net/sourceforge/plantuml/bpm/CommandMerge.java index 3efe81dcd..eb125332e 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandMerge.java +++ b/src/net/sourceforge/plantuml/bpm/CommandMerge.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandMerge extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { final BpmEvent event = new BpmEventAdd(new BpmElement(arg.get("ID", 0), BpmElementType.MERGE, null)); return diagram.addEvent(event); } diff --git a/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java b/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java index bfa799f4b..1664095d0 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java +++ b/src/net/sourceforge/plantuml/bpm/CommandNewBranch.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandNewBranch extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { return diagram.newBranch(); } diff --git a/src/net/sourceforge/plantuml/bpm/CommandResume.java b/src/net/sourceforge/plantuml/bpm/CommandResume.java index 7272630b2..cb57fa684 100644 --- a/src/net/sourceforge/plantuml/bpm/CommandResume.java +++ b/src/net/sourceforge/plantuml/bpm/CommandResume.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.bpm; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandResume extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(BpmDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(BpmDiagram diagram, LineLocation location, RegexResult arg) { final BpmEvent event = new BpmEventResume(arg.get("ID", 0)); return diagram.addEvent(event); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandAllowMixing.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandAllowMixing.java index 5371a7007..3665869e9 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandAllowMixing.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandAllowMixing.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.classdiagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.classdiagram.ClassDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -56,7 +57,7 @@ public class CommandAllowMixing extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ClassDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { diagram.setAllowMixing(true); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java index e2358011a..2c8d8eab1 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -108,7 +109,7 @@ public class CommandCreateClass extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ClassDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final LeafType type = LeafType.getLeafType(StringUtils.goUpperCase(arg.get("TYPE", 0))); final Code code = Code.of(arg.getLazzy("CODE", 0)).eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); final String display = arg.getLazzy("DISPLAY", 0); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index cd3c925fb..78cef5920 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -114,20 +115,19 @@ public class CommandCreateClassMultilines extends CommandMultilines2 0 && VisibilityModifier.isVisibilityCharacter(s)) { + for (StringLocated s : lines) { + if (s.getString().length() > 0 && VisibilityModifier.isVisibilityCharacter(s.getString())) { diagram.setVisibilityModifierPresent(true); } - entity.getBodier().addFieldOrMethod(s.toString(), entity); + if (s instanceof StringLocated) { + entity.getBodier().addFieldOrMethod(((StringLocated) s).getString(), entity); + } else { + entity.getBodier().addFieldOrMethod(s.toString(), entity); + } } if (url != null) { entity.addUrl(url); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java index 45eeae9e2..1b460abf9 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -110,7 +111,7 @@ public class CommandCreateElementFull2 extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(ClassDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { if (mode == Mode.NORMAL_KEYWORD && diagram.isAllowMixing() == false) { return CommandExecutionResult .error("Use 'allowmixing' if you want to mix classes and other UML elements."); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow2.java index 82afd24c9..295273c3e 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow2.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow2.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.classdiagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -57,7 +58,7 @@ public class CommandHideShow2 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(CucaDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(CucaDiagram diagram, LineLocation location, RegexResult arg) { final char tmp = arg.get("COMMAND", 0).charAt(0); final boolean show = tmp == 's' || tmp == 'S'; diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java index 2b9e8f3dd..727a54b3b 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.classdiagram.command; import java.util.EnumSet; import java.util.Set; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -93,7 +94,7 @@ public class CommandHideShowByGender extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(UmlDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(UmlDiagram diagram, LineLocation location, RegexResult arg) { if (diagram instanceof AbstractClassOrObjectDiagram) { return executeClassDiagram((AbstractClassOrObjectDiagram) diagram, arg); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByVisibility.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByVisibility.java index 118153a4b..af8a73a46 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByVisibility.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByVisibility.java @@ -39,6 +39,7 @@ import java.util.EnumSet; import java.util.Set; import java.util.StringTokenizer; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.classdiagram.ClassDiagram; @@ -73,7 +74,7 @@ public class CommandHideShowByVisibility extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(UmlDiagram classDiagram, RegexResult arg) { + protected CommandExecutionResult executeArg(UmlDiagram classDiagram, LineLocation location, RegexResult arg) { if (classDiagram instanceof ClassDiagram) { return executeArgClass((ClassDiagram) classDiagram, arg); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificClass.java index 302a12dfa..484ff4f94 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowSpecificClass.java @@ -35,15 +35,13 @@ */ package net.sourceforge.plantuml.classdiagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; -import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.CucaDiagram; -import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.LeafType; public class CommandHideShowSpecificClass extends SingleLineCommand2 { @@ -60,7 +58,7 @@ public class CommandHideShowSpecificClass extends SingleLineCommand2 { @@ -58,7 +58,7 @@ public class CommandHideShowSpecificStereotype extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ClassDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { diagram.layoutNewLine(); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java index c4fcb1f9f..b1abad29e 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.Url; @@ -60,7 +61,6 @@ import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; import net.sourceforge.plantuml.graphic.color.ColorParser; import net.sourceforge.plantuml.graphic.color.ColorType; -import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; final public class CommandLinkClass extends SingleLineCommand2 { @@ -134,7 +134,7 @@ final public class CommandLinkClass extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(CucaDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(CucaDiagram diagram, LineLocation location, RegexResult arg) { final boolean show = arg.get("COMMAND", 0).equalsIgnoreCase("restore"); final String what = arg.get("WHAT", 0).trim(); diff --git a/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java index 37ad8f651..ee80186ed 100644 --- a/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java +++ b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.code; import java.io.IOException; import java.io.StringReader; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; @@ -55,13 +55,13 @@ public class ArobaseStringCompressor implements StringCompressor { final ReadLine r = new UncommentReadLine(ReadLineReader.create(new StringReader(data), "COMPRESS")); final StringBuilder sb = new StringBuilder(); final StringBuilder full = new StringBuilder(); - CharSequence2 s = null; + StringLocated s = null; boolean startDone = false; while ((s = r.readLine()) != null) { append(full, s); - if (s.toString2().startsWith("@startuml")) { + if (s.getString().startsWith("@startuml")) { startDone = true; - } else if (s.toString2().startsWith("@enduml")) { + } else if (s.getString().startsWith("@enduml")) { return sb.toString(); } else if (startDone) { append(sb, s); @@ -73,11 +73,11 @@ public class ArobaseStringCompressor implements StringCompressor { return sb.toString(); } - private void append(final StringBuilder sb, CharSequence2 s) { + private void append(final StringBuilder sb, StringLocated s) { if (sb.length() > 0) { sb.append('\n'); } - sb.append(s.toString2()); + sb.append(s.getString()); } private String compressOld(String s) throws IOException { diff --git a/src/net/sourceforge/plantuml/command/BlocLines.java b/src/net/sourceforge/plantuml/command/BlocLines.java index c4ad7f469..19f0ab2c5 100644 --- a/src/net/sourceforge/plantuml/command/BlocLines.java +++ b/src/net/sourceforge/plantuml/command/BlocLines.java @@ -40,99 +40,153 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import net.sourceforge.plantuml.BackSlash; -import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.cucadiagram.Display; -public class BlocLines implements Iterable { +public class BlocLines implements Iterable { - private List lines; + private List lines; + + private void check() { + // for (CharSequence s : lines) { + // // if (s == null) { + // // continue; + // // } + // if (s instanceof String) { + // continue; + // } + // // if (s instanceof Stereotype) { + // // continue; + // // } + // if (s instanceof CharSequence2) { + // continue; + // } + // // if (s instanceof MessageNumber) { + // // continue; + // // } + // // if (s instanceof EmbeddedDiagram) { + // // continue; + // // } + // System.err.println("PB2=" + s); + // System.err.println("PB=" + s.getClass()); + // Thread.dumpStack(); + // System.exit(0); + // } + } @Override public String toString() { return lines.toString(); } - public static BlocLines load(File f) throws IOException { - final List result = new ArrayList(); + public static BlocLines load(File f, LineLocation location) throws IOException { + final List result = new ArrayList(); final BufferedReader br = new BufferedReader(new FileReader(f)); String s; while ((s = br.readLine()) != null) { - result.add(s); + result.add(new StringLocated(s, location)); } br.close(); return new BlocLines(result); } - private BlocLines(List lines) { - this.lines = (List) Collections.unmodifiableList(lines); + private BlocLines(List lines) { + this.lines = Collections.unmodifiableList(lines); + this.check(); } public Display toDisplay() { - return Display.create(lines); + return Display.createFoo(lines); } - public static BlocLines single(CharSequence single) { - return new BlocLines(Arrays.asList(single)); + public static BlocLines single2(StringLocated single) { + final List result = new ArrayList(); + result.add(single); + return new BlocLines(result); } - public static BlocLines getWithNewlines(CharSequence s) { - return new BlocLines(BackSlash.getWithNewlines(s)); + public static BlocLines singleString(String single) { + final List result = new ArrayList(); + result.add(new StringLocated(single, null)); + return new BlocLines(result); + } + + public static BlocLines getWithNewlines(String s) { + final List result = new ArrayList(); + for (String cs : BackSlash.getWithNewlines(s)) { + result.add(new StringLocated(cs, null)); + } + return new BlocLines(result); } public BlocLines() { - this(new ArrayList()); + this(new ArrayList()); } - public BlocLines add2(CharSequence s) { - final List copy = new ArrayList(lines); + public BlocLines add2(StringLocated s) { + final List copy = new ArrayList(lines); copy.add(s); return new BlocLines(copy); } - public List getLines() { - return lines; + public BlocLines addString(String s) { + final List copy = new ArrayList(lines); + copy.add(new StringLocated(s, null)); + return new BlocLines(copy); + } + + // public List getLines() { + // return lines2; + // } + + public List getLinesAsStringForSprite() { + final List result = new ArrayList(); + for (StringLocated s : lines) { + result.add(s.getString()); + } + return result; } public int size() { return lines.size(); } - public CharSequence get499(int i) { + public StringLocated get499(int i) { return lines.get(i); } - public CharSequence getFirst499() { + public StringLocated getFirst499() { if (lines.size() == 0) { return null; } return lines.get(0); } - public CharSequence getLast499() { + public StringLocated getLast499() { return lines.get(lines.size() - 1); } public BlocLines cleanList2(MultilinesStrategy strategy) { - final List copy = new ArrayList(lines); + final List copy = new ArrayList(lines); strategy.cleanList(copy); return new BlocLines(copy); } public BlocLines trim(boolean removeEmptyLines) { - final List copy = new ArrayList(lines); + final List copy = new ArrayList(lines); for (int i = 0; i < copy.size(); i++) { - final CharSequence s = copy.get(i); - copy.set(i, StringUtils.trin(s)); + final StringLocated s = copy.get(i); + copy.set(i, new StringLocated(s.getStringTrimmed(), s.getLocation())); } if (removeEmptyLines) { - for (final Iterator it = copy.iterator(); it.hasNext();) { - if (it.next().length() == 0) { + for (final Iterator it = copy.iterator(); it.hasNext();) { + if (it.next().getString().length() == 0) { it.remove(); } } @@ -144,26 +198,26 @@ public class BlocLines implements Iterable { if (firstColumnRemovable(lines) == false) { return this; } - final List copy = new ArrayList(lines); + final List copy = new ArrayList(lines); do { for (int i = 0; i < copy.size(); i++) { - final CharSequence s = copy.get(i); - if (s.length() > 0) { - copy.set(i, s.subSequence(1, s.length())); + final StringLocated s = copy.get(i); + if (s.getString().length() > 0) { + copy.set(i, s.sub(1, s.getString().length())); } } } while (firstColumnRemovable(copy)); return new BlocLines(copy); } - private static boolean firstColumnRemovable(List data) { + private static boolean firstColumnRemovable(List data) { boolean allEmpty = true; - for (CharSequence s : data) { - if (s.length() == 0) { + for (StringLocated s : data) { + if (s.getString().length() == 0) { continue; } allEmpty = false; - final char c = s.charAt(0); + final char c = s.getString().charAt(0); if (c != ' ' && c != '\t') { return false; } @@ -172,39 +226,39 @@ public class BlocLines implements Iterable { } public char getLastChar() { - final CharSequence s = lines.get(lines.size() - 1); - return s.charAt(s.length() - 1); + final StringLocated s = lines.get(lines.size() - 1); + return s.getString().charAt(s.getString().length() - 1); } public BlocLines removeStartingAndEnding2(String data) { if (lines.size() == 0) { return this; } - final List copy = new ArrayList(lines); - copy.set(0, data); + final List copy = new ArrayList(lines); + copy.set(0, new StringLocated(data, null)); final int n = copy.size() - 1; - final CharSequence s = copy.get(n); - copy.set(n, s.subSequence(0, s.length() - 1)); + final StringLocated s = copy.get(n); + copy.set(n, s.sub(0, s.getString().length() - 1)); return new BlocLines(copy); } public BlocLines toSingleLineWithHiddenNewLine() { final StringBuilder sb = new StringBuilder(); - for (CharSequence line : lines) { - sb.append(line); + for (StringLocated line : lines) { + sb.append(line.getString()); sb.append(BackSlash.hiddenNewLine()); } - return single(sb.substring(0, sb.length() - 1)); + return singleString(sb.substring(0, sb.length() - 1).toString()); } public BlocLines trimSmart(int referenceLine) { if (lines.size() <= referenceLine) { return this; } - final List copy = new ArrayList(lines); - final int nbStartingSpace = nbStartingSpace(copy.get(referenceLine)); + final List copy = new ArrayList(lines); + final int nbStartingSpace = nbStartingSpace(copy.get(referenceLine).getString()); for (int i = referenceLine; i < copy.size(); i++) { - final CharSequence s = copy.get(i); + final StringLocated s = copy.get(i); copy.set(i, removeStartingSpaces(s, nbStartingSpace)); } return new BlocLines(copy); @@ -222,22 +276,22 @@ public class BlocLines implements Iterable { return c == ' ' || c == '\t'; } - private static CharSequence removeStartingSpaces(CharSequence arg, int nbStartingSpace) { - if (arg.length() == 0) { + private static StringLocated removeStartingSpaces(StringLocated arg, int nbStartingSpace) { + if (arg.getString().length() == 0) { return arg; } int i = 0; - while (i < nbStartingSpace && i < arg.length() && isSpaceOrTab(arg.charAt(i))) { + while (i < nbStartingSpace && i < arg.getString().length() && isSpaceOrTab(arg.getString().charAt(i))) { i++; } if (i == 0) { return arg; } - return arg.subSequence(i, arg.length()); + return arg.sub(i, arg.getString().length()); } public BlocLines subExtract(int margeStart, int margeEnd) { - List copy = new ArrayList(lines); + List copy = new ArrayList(lines); copy = copy.subList(margeStart, copy.size() - margeEnd); return new BlocLines(copy); } @@ -246,7 +300,7 @@ public class BlocLines implements Iterable { return new BlocLines(lines.subList(start, end)); } - public Iterator iterator() { + public Iterator iterator() { return lines.iterator(); } @@ -254,12 +308,12 @@ public class BlocLines implements Iterable { if (size() < 2) { return this; } - final String first = StringUtils.trin(getFirst499()); - final String second = StringUtils.trin(get499(1)); + final String first = getFirst499().getStringTrimmed(); + final String second = get499(1).getStringTrimmed(); if (first.endsWith("{") == false && second.equals("{")) { final String vline = first + " {"; - final List result = new ArrayList(); - result.add(vline); + final List result = new ArrayList(); + result.add(new StringLocated(vline, null)); result.addAll(this.lines.subList(2, this.lines.size())); return new BlocLines(result); } diff --git a/src/net/sourceforge/plantuml/command/CommandAffineTransformMultiline.java b/src/net/sourceforge/plantuml/command/CommandAffineTransformMultiline.java index 8daccdeca..66098be1e 100644 --- a/src/net/sourceforge/plantuml/command/CommandAffineTransformMultiline.java +++ b/src/net/sourceforge/plantuml/command/CommandAffineTransformMultiline.java @@ -49,9 +49,9 @@ public class CommandAffineTransformMultiline extends CommandMultilines implements Command { return CommandControl.NOT_OK; } lines = lines.toSingleLineWithHiddenNewLine(); - if (cmd.isForbidden(lines.getFirst499())) { + if (cmd.isForbidden(lines.getFirst499().getString())) { return CommandControl.NOT_OK; } final CommandControl tmp = cmd.isValid(lines); diff --git a/src/net/sourceforge/plantuml/command/CommandFooter.java b/src/net/sourceforge/plantuml/command/CommandFooter.java index 2f7ca79d5..486431648 100644 --- a/src/net/sourceforge/plantuml/command/CommandFooter.java +++ b/src/net/sourceforge/plantuml/command/CommandFooter.java @@ -39,9 +39,7 @@ import java.util.List; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.cucadiagram.Display; -import net.sourceforge.plantuml.cucadiagram.DisplaySection; import net.sourceforge.plantuml.graphic.HorizontalAlignment; -import net.sourceforge.plantuml.graphic.VerticalAlignment; public class CommandFooter extends SingleLineCommand { diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines.java b/src/net/sourceforge/plantuml/command/CommandMultilines.java index 719a2fecd..23b4658e2 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilines.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilines.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.command; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; @@ -62,7 +61,7 @@ public abstract class CommandMultilines implements Command if (isCommandForbidden()) { return CommandControl.NOT_OK; } - Matcher2 m1 = starting.matcher(StringUtils.trin(lines.getFirst499())); + Matcher2 m1 = starting.matcher(lines.getFirst499().getStringTrimmed()); if (m1.matches() == false) { return CommandControl.NOT_OK; } @@ -70,7 +69,7 @@ public abstract class CommandMultilines implements Command return CommandControl.OK_PARTIAL; } - m1 = MyPattern.cmpile(getPatternEnd()).matcher(StringUtils.trin(lines.getLast499())); + m1 = MyPattern.cmpile(getPatternEnd()).matcher(lines.getLast499().getStringTrimmed()); if (m1.matches() == false) { return CommandControl.OK_PARTIAL; } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines2.java b/src/net/sourceforge/plantuml/command/CommandMultilines2.java index a89b132f1..c6e78a598 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilines2.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilines2.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.command; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; @@ -71,20 +72,20 @@ public abstract class CommandMultilines2 implements Command implements Command implements Command implements Command implements Com if (isCommandForbidden()) { return CommandControl.NOT_OK; } - final Matcher2 m1 = starting.matcher(StringUtils.trin(lines.getFirst499())); + final Matcher2 m1 = starting.matcher(lines.getFirst499().getStringTrimmed()); if (m1.matches() == false) { return CommandControl.NOT_OK; } @@ -80,8 +80,8 @@ public abstract class CommandMultilinesBracket implements Com } int level = 1; - for (CharSequence cs : lines.subExtract(1, 0)) { - final String s = StringUtils.trin(cs); + for (StringLocated cs : lines.subExtract(1, 0)) { + final String s = cs.getStringTrimmed(); if (isLineConsistent(s, level) == false) { return CommandControl.NOT_OK; } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java index 48ef832c5..086571fec 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.command; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.cucadiagram.Display; @@ -54,7 +53,7 @@ public class CommandMultilinesFooter extends CommandMultilines { public CommandExecutionResult execute(final UmlDiagram diagram, BlocLines lines) { lines = lines.trim(false); - final Matcher2 m = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final Matcher2 m = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); if (m.find() == false) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java b/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java index 00c4fb137..357290127 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.command; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.cucadiagram.Display; @@ -54,7 +53,7 @@ public class CommandMultilinesHeader extends CommandMultilines { public CommandExecutionResult execute(final UmlDiagram diagram, BlocLines lines) { lines = lines.trim(false); - final Matcher2 m = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final Matcher2 m = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); if (m.find() == false) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java b/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java index b79d14b09..e75591768 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.command; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -67,7 +66,7 @@ public class CommandMultilinesLegend extends CommandMultilines2 { @Override protected CommandExecutionResult executeNow(UmlDiagram diagram, BlocLines lines) { lines = lines.trimSmart(1); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); final String align = line0.get("ALIGN", 0); final String valign = line0.get("VALIGN", 0); lines = lines.subExtract(1, 1); diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace.java b/src/net/sourceforge/plantuml/command/CommandNamespace.java index 9d64f6b03..fbf6f1b04 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespace.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespace.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -71,7 +72,7 @@ public class CommandNamespace extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(ClassDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final Code code = Code.of(arg.get("NAME", 0)); final IGroup currentPackage = diagram.getCurrentGroup(); diagram.gotoGroup2(code, Display.getWithNewlines(code), GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); diff --git a/src/net/sourceforge/plantuml/command/CommandPackage.java b/src/net/sourceforge/plantuml/command/CommandPackage.java index b2c50a981..050a244e6 100644 --- a/src/net/sourceforge/plantuml/command/CommandPackage.java +++ b/src/net/sourceforge/plantuml/command/CommandPackage.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -92,7 +93,7 @@ public class CommandPackage extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(AbstractEntityDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(AbstractEntityDiagram diagram, LineLocation location, RegexResult arg) { final Code code; final String display; final String name = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("NAME", 0)); diff --git a/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java b/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java index 09db4d4ed..f0c1c454d 100644 --- a/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java +++ b/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java @@ -63,7 +63,7 @@ public class CommandSkinParamMultilines extends CommandMultilinesBracket { } @Override - protected CommandExecutionResult executeArg(UmlDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(UmlDiagram system, LineLocation location, RegexResult arg) { final String src = arg.get("FILE", 0); final Sprite sprite; try { diff --git a/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java b/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java index 3ce3e2871..9dcec7ed5 100644 --- a/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java +++ b/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.WithSprite; import net.sourceforge.plantuml.command.note.SingleMultiFactoryCommand; @@ -74,8 +75,8 @@ public final class FactorySpriteCommand implements SingleMultiFactoryCommand(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final WithSprite system, RegexResult arg) { - return executeInternal(system, arg, Arrays.asList((CharSequence) arg.get("DATA", 0))); + protected CommandExecutionResult executeArg(final WithSprite system, LineLocation location, RegexResult arg) { + return executeInternal(system, arg, Arrays.asList((String) arg.get("DATA", 0))); } }; @@ -91,21 +92,21 @@ public final class FactorySpriteCommand implements SingleMultiFactoryCommand strings) { + final List strings) { try { final Sprite sprite; if (line0.get("DIM", 0) == null) { @@ -135,9 +136,9 @@ public final class FactorySpriteCommand implements SingleMultiFactoryCommand strings) { + private String concat(final List strings) { final StringBuilder sb = new StringBuilder(); - for (CharSequence s : strings) { + for (String s : strings) { sb.append(StringUtils.trin(s)); } return sb.toString(); diff --git a/src/net/sourceforge/plantuml/command/MultilinesStrategy.java b/src/net/sourceforge/plantuml/command/MultilinesStrategy.java index de58d9340..e21da644d 100644 --- a/src/net/sourceforge/plantuml/command/MultilinesStrategy.java +++ b/src/net/sourceforge/plantuml/command/MultilinesStrategy.java @@ -38,27 +38,28 @@ package net.sourceforge.plantuml.command; import java.util.Iterator; import java.util.List; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; public enum MultilinesStrategy { REMOVE_STARTING_QUOTE, KEEP_STARTING_QUOTE; - public void cleanList(List lines) { + public void cleanList(List lines) { if (this == REMOVE_STARTING_QUOTE) { filterQuote(lines); } } - private void filterQuote(List lines) { - for (final Iterator it = lines.iterator(); it.hasNext();) { - final CharSequence s = it.next(); + private void filterQuote(List lines) { + for (final Iterator it = lines.iterator(); it.hasNext();) { + final StringLocated s = it.next(); if (hasStartingQuote(s)) { it.remove(); } } } - private boolean hasStartingQuote(CharSequence s) { - return StringUtils.trinNoTrace(s).startsWith("\'"); + private boolean hasStartingQuote(StringLocated s) { + return StringUtils.trinNoTrace(s.getString()).startsWith("\'"); } } diff --git a/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java b/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java index 16bd5c488..f3a4ef7cd 100644 --- a/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java @@ -36,10 +36,10 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.CharSequence2; 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; @@ -62,23 +62,23 @@ public abstract class PSystemBasicFactory

extends PSy return null; } - private boolean isEmptyLine(CharSequence2 result) { - return result.trin().length() == 0; + private boolean isEmptyLine(StringLocated result) { + return result.getStringTrimmed().length() == 0; } final public Diagram createSystem(UmlSource source) { source = source.removeInitialSkinparam(); final IteratorCounter2 it = source.iterator2(); - final CharSequence2 startLine = it.next(); - P system = init(startLine.toString2()); + final StringLocated startLine = it.next(); + P system = init(startLine.getString()); boolean first = true; while (it.hasNext()) { - final CharSequence2 s = it.next(); + final StringLocated s = it.next(); if (first && s != null && isEmptyLine(s)) { continue; } first = false; - if (StartUtils.isArobaseEndDiagram(s)) { + if (StartUtils.isArobaseEndDiagram(s.getString())) { if (source.getTotalLineCount() == 2 && source.isStartDef() == false) { return buildEmptyError(source, s.getLocation()); } @@ -87,7 +87,7 @@ public abstract class PSystemBasicFactory

extends PSy } return system; } - system = executeLine(system, s.toString2()); + 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); diff --git a/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java b/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java index dd9762179..4c964f121 100644 --- a/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java @@ -36,10 +36,10 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.CharSequence2; 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; @@ -64,19 +64,19 @@ public abstract class PSystemSingleLineFactory extends PSystemAbstractFactory { return buildEmptyError(source, it.peek().getLocation()); } - final CharSequence2 startLine = it.next(); - if (StartUtils.isArobaseStartDiagram(startLine) == false) { + final StringLocated startLine = it.next(); + if (StartUtils.isArobaseStartDiagram(startLine.getString()) == false) { throw new UnsupportedOperationException(); } if (it.hasNext() == false) { return buildEmptyError(source, startLine.getLocation()); } - final CharSequence2 s = it.next(); - if (StartUtils.isArobaseEndDiagram(s)) { + final StringLocated s = it.next(); + if (StartUtils.isArobaseEndDiagram(s.getString())) { return buildEmptyError(source, s.getLocation()); } - final AbstractPSystem sys = executeLine(s.toString2()); + final AbstractPSystem sys = executeLine(s.getString()); if (sys == null) { final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", /* it.currentNum() - 1, */s.getLocation()); diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand.java b/src/net/sourceforge/plantuml/command/SingleLineCommand.java index 772f3fcaf..b26c2453a 100644 --- a/src/net/sourceforge/plantuml/command/SingleLineCommand.java +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand.java @@ -69,7 +69,7 @@ public abstract class SingleLineCommand implements Command if (isCommandForbidden()) { return CommandControl.NOT_OK; } - final String line = StringUtils.trin(lines.getFirst499()); + final String line = lines.getFirst499().getStringTrimmed(); final Matcher2 m = pattern.matcher(line); final boolean result = m.find(); if (result) { @@ -89,7 +89,7 @@ public abstract class SingleLineCommand implements Command if (lines.size() != 1) { throw new IllegalArgumentException(); } - final String line = StringUtils.trin(lines.getFirst499()); + final String line = lines.getFirst499().getStringTrimmed(); if (isForbidden(line)) { return CommandExecutionResult.error("Syntax error: " + line); } diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java index 1ba9e4980..8959e003d 100644 --- a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java @@ -35,8 +35,9 @@ */ package net.sourceforge.plantuml.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.PSystemError; -import net.sourceforge.plantuml.StringUtils; +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; @@ -70,11 +71,11 @@ public abstract class SingleLineCommand2 implements Command implements Command implements Command implements Command implements Command(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final ActivityDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(final ActivityDiagram system, LineLocation location, RegexResult arg) { final IEntity note = system.createNote(UniqueSequence.getCode("GN"), Display.getWithNewlines(arg.get("NOTE", 0))); return executeInternal(system, arg, note); diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java index 43180178c..2f76f49b1 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java @@ -35,7 +35,7 @@ */ package net.sourceforge.plantuml.command.note; -import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; import net.sourceforge.plantuml.classdiagram.command.CommandCreateClassMultilines; import net.sourceforge.plantuml.command.BlocLines; @@ -84,7 +84,7 @@ public final class FactoryNoteCommand implements SingleMultiFactoryCommand(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final AbstractEntityDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(final AbstractEntityDiagram system, LineLocation location, RegexResult arg) { final String display = arg.get("DISPLAY", 0); return executeInternal(system, arg, BlocLines.getWithNewlines(display)); } @@ -103,7 +103,7 @@ public final class FactoryNoteCommand implements SingleMultiFactoryCommand(getRegexConcatSingleLine(partialPattern)) { @Override - protected CommandExecutionResult executeArg(final AbstractEntityDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(final AbstractEntityDiagram system, LineLocation location, RegexResult arg) { final String s = arg.get("NOTE", 0); return executeInternal(arg, system, null, BlocLines.getWithNewlines(s)); } @@ -139,7 +140,7 @@ public final class FactoryNoteOnEntityCommand implements SingleMultiFactoryComma protected CommandExecutionResult executeNow(final AbstractEntityDiagram system, BlocLines lines) { // StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java index b55c61e1c..599445720 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.command.note; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -88,7 +89,7 @@ public final class FactoryNoteOnLinkCommand implements SingleMultiFactoryCommand } protected CommandExecutionResult executeNow(final CucaDiagram system, BlocLines lines) { - final String line0 = lines.getFirst499().toString(); + final String line0 = lines.getFirst499().getString(); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); if (lines.size() > 0) { @@ -105,7 +106,7 @@ public final class FactoryNoteOnLinkCommand implements SingleMultiFactoryCommand return new SingleLineCommand2(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final CucaDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(final CucaDiagram system, LineLocation location, RegexResult arg) { final BlocLines note = BlocLines.getWithNewlines(arg.get("NOTE", 0)); return executeInternal(system, note, arg); } diff --git a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java index 65f2590b3..aa02d55c9 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java @@ -100,7 +100,7 @@ public final class FactoryTipOnEntityCommand implements SingleMultiFactoryComman protected CommandExecutionResult executeNow(final AbstractEntityDiagram system, BlocLines lines) { // StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java index 0436e7deb..04c8b3c1f 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java @@ -37,6 +37,7 @@ 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; import net.sourceforge.plantuml.UrlBuilder; @@ -67,6 +68,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma private RegexConcat getRegexConcatMultiLine() { return new RegexConcat(// new RegexLeaf("^"), // + new RegexLeaf("PARALLEL", "(&[%s]*)?"), // new RegexLeaf("VMERGE", "(/)?[%s]*"), // new RegexLeaf("STYLE", "(note|hnote|rnote)"), // new RegexLeaf("[%s]*"), // @@ -82,6 +84,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma private RegexConcat getRegexConcatSingleLine() { return new RegexConcat(// new RegexLeaf("^"), // + new RegexLeaf("PARALLEL", "(&[%s]*)?"), // new RegexLeaf("VMERGE", "(/)?[%s]*"), // new RegexLeaf("STYLE", "(note|hnote|rnote)"), // new RegexLeaf("[%s]*"), // @@ -110,7 +113,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma } protected CommandExecutionResult executeNow(final SequenceDiagram system, BlocLines lines) { - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); return executeInternal(system, line0, lines); @@ -122,7 +125,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma return new SingleLineCommand2(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final SequenceDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(final SequenceDiagram system, LineLocation location, RegexResult arg) { return executeInternal(system, arg, BlocLines.getWithNewlines(arg.get("NOTE", 0))); } @@ -137,6 +140,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma if (strings.size() > 0) { final boolean tryMerge = arg.get("VMERGE", 0) != null; + final boolean parallel = arg.get("PARALLEL", 0) != null; final Display display = diagram.manageVariable(strings.toDisplay()); final Note note = new Note(p, position, display); Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet()); @@ -153,6 +157,9 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma final Url urlLink = urlBuilder.getUrl(arg.get("URL", 0)); note.setUrl(urlLink); } + if (parallel) { + note.goParallel(); + } diagram.addNote(note, tryMerge); } return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java index 35b9a302f..879d8d979 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java @@ -37,6 +37,7 @@ 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; import net.sourceforge.plantuml.UrlBuilder; @@ -97,7 +98,7 @@ public final class FactorySequenceNoteOnArrowCommand implements SingleMultiFacto return new SingleLineCommand2(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final SequenceDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(final SequenceDiagram system, LineLocation location, RegexResult arg) { return executeInternal(system, arg, BlocLines.getWithNewlines(arg.get("NOTE", 0))); } @@ -114,7 +115,7 @@ public final class FactorySequenceNoteOnArrowCommand implements SingleMultiFacto } protected CommandExecutionResult executeNow(final SequenceDiagram system, BlocLines lines) { - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); return executeInternal(system, line0, lines); diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java index 669b57e30..97cc403d1 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.command.note.sequence; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -96,7 +97,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF return new SingleLineCommand2(getRegexConcatSingleLine()) { @Override - protected CommandExecutionResult executeArg(final SequenceDiagram system, 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); @@ -115,7 +116,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF } protected CommandExecutionResult executeNow(final SequenceDiagram system, BlocLines lines) { - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); return executeInternal(system, line0, lines); diff --git a/src/net/sourceforge/plantuml/core/DiagramType.java b/src/net/sourceforge/plantuml/core/DiagramType.java index 6e99cc493..db4317d06 100644 --- a/src/net/sourceforge/plantuml/core/DiagramType.java +++ b/src/net/sourceforge/plantuml/core/DiagramType.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.core; import net.sourceforge.plantuml.utils.StartUtils; public enum DiagramType { - UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, NW, MINDMAP, UNKNOWN; + UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, NW, MINDMAP, WBS, UNKNOWN; static public DiagramType getTypeFromArobaseStart(String s) { s = s.toLowerCase(); @@ -96,6 +96,9 @@ public enum DiagramType { if (StartUtils.startsWithSymbolAnd("startmindmap", s)) { return MINDMAP; } + if (StartUtils.startsWithSymbolAnd("startwbs", s)) { + return WBS; + } return UNKNOWN; } } diff --git a/src/net/sourceforge/plantuml/core/UmlSource.java b/src/net/sourceforge/plantuml/core/UmlSource.java index 5d8b3ee3f..e641f86f4 100644 --- a/src/net/sourceforge/plantuml/core/UmlSource.java +++ b/src/net/sourceforge/plantuml/core/UmlSource.java @@ -41,9 +41,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.plantuml.BackSlash; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; @@ -64,13 +63,13 @@ import net.sourceforge.plantuml.version.IteratorCounter2Impl; */ final public class UmlSource { - final private List source; + final private List source; public UmlSource removeInitialSkinparam() { if (hasInitialSkinparam(source) == false) { return this; } - final List copy = new ArrayList(source); + final List copy = new ArrayList(source); while (hasInitialSkinparam(copy)) { copy.remove(1); } @@ -78,19 +77,19 @@ final public class UmlSource { } public boolean containsIgnoreCase(String searched) { - for (CharSequence2 s : source) { - if (StringUtils.goLowerCase(s.toString()).contains(searched)) { + for (StringLocated s : source) { + if (StringUtils.goLowerCase(s.getString()).contains(searched)) { return true; } } return false; } - private static boolean hasInitialSkinparam(final List copy) { - return copy.size() > 1 && (copy.get(1).startsWith("skinparam ") || copy.get(1).startsWith("skinparamlocked ")); + private static boolean hasInitialSkinparam(final List copy) { + return copy.size() > 1 && (copy.get(1).getString().startsWith("skinparam ") || copy.get(1).getString().startsWith("skinparamlocked ")); } - private UmlSource(List source) { + private UmlSource(List source) { this.source = source; } @@ -102,18 +101,18 @@ final public class UmlSource { * @param checkEndingBackslash * true if an ending backslash means that a line has to be collapsed with the following one. */ - public UmlSource(List data, boolean checkEndingBackslash) { - this(new ArrayList()); + public UmlSource(List data, boolean checkEndingBackslash) { + this(new ArrayList()); if (checkEndingBackslash) { final StringBuilder pending = new StringBuilder(); - for (CharSequence2 cs : data) { - final String s = cs.toString2(); + for (StringLocated cs : data) { + final String s = cs.getString(); if (StringUtils.endsWithBackslash(s)) { pending.append(s.substring(0, s.length() - 1)); } else { pending.append(s); - this.source.add(new CharSequence2Impl(pending.toString(), cs.getLocation())); + this.source.add(new StringLocated(pending.toString(), cs.getLocation())); pending.setLength(0); } } @@ -128,7 +127,7 @@ final public class UmlSource { * @return the type of the diagram. */ public DiagramType getDiagramType() { - return DiagramType.getTypeFromArobaseStart(source.get(0).toString2()); + return DiagramType.getTypeFromArobaseStart(source.get(0).getString()); } /** @@ -147,8 +146,8 @@ final public class UmlSource { */ public String getPlainString() { final StringBuilder sb = new StringBuilder(); - for (CharSequence2 s : source) { - sb.append(s); + for (StringLocated s : source) { + sb.append(s.getString()); sb.append('\r'); sb.append(BackSlash.CHAR_NEWLINE); } @@ -167,9 +166,9 @@ final public class UmlSource { } public String getLine(LineLocation n) { - for (CharSequence2 s : source) { + for (StringLocated s : source) { if (s.getLocation().compareTo(n) == 0) { - return s.toString(); + return s.getString(); } } return null; @@ -190,17 +189,17 @@ final public class UmlSource { * @return true if the diagram does not contain information. */ public boolean isEmpty() { - for (CharSequence2 s : source) { - if (StartUtils.isArobaseStartDiagram(s)) { + for (StringLocated s : source) { + if (StartUtils.isArobaseStartDiagram(s.getString())) { continue; } - if (StartUtils.isArobaseEndDiagram(s)) { + if (StartUtils.isArobaseEndDiagram(s.getString())) { continue; } - if (s.toString().matches("\\s*'.*")) { + if (s.getString().matches("\\s*'.*")) { continue; } - if (StringUtils.trin(s).length() != 0) { + if (StringUtils.trin(s.getString()).length() != 0) { return false; } } @@ -214,8 +213,8 @@ final public class UmlSource { */ public Display getTitle() { final Pattern2 p = MyPattern.cmpile("(?i)^[%s]*title[%s]+(.+)$"); - for (CharSequence2 s : source) { - final Matcher2 m = p.matcher(s); + for (StringLocated s : source) { + final Matcher2 m = p.matcher(s.getString()); final boolean ok = m.matches(); if (ok) { return Display.create(m.group(1)); @@ -225,12 +224,12 @@ final public class UmlSource { } public boolean isStartDef() { - return source.get(0).startsWith("@startdef"); + return source.get(0).getString().startsWith("@startdef"); } public String getId() { final Pattern p = Pattern.compile("id=([\\w]+)\\b"); - final Matcher m = p.matcher(source.get(0)); + final Matcher m = p.matcher(source.get(0).getString()); if (m.find()) { return m.group(1); } diff --git a/src/net/sourceforge/plantuml/creole/AbstractAtom.java b/src/net/sourceforge/plantuml/creole/AbstractAtom.java new file mode 100644 index 000000000..b0cf83113 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/AbstractAtom.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole; + +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public abstract class AbstractAtom implements Atom { + + public List splitInTwo(StringBounder stringBounder, double width) { + throw new UnsupportedOperationException(getClass().toString()); + } + +} diff --git a/src/net/sourceforge/plantuml/creole/Atom.java b/src/net/sourceforge/plantuml/creole/Atom.java index e963b40f2..5c7404176 100644 --- a/src/net/sourceforge/plantuml/creole/Atom.java +++ b/src/net/sourceforge/plantuml/creole/Atom.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.creole; import java.awt.geom.Dimension2D; +import java.util.List; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -48,5 +49,7 @@ public interface Atom extends UShape { public double getStartingAltitude(StringBounder stringBounder); public void drawU(UGraphic ug); - + + public List splitInTwo(StringBounder stringBounder, double width); + } diff --git a/src/net/sourceforge/plantuml/creole/AtomHorizontalTexts.java b/src/net/sourceforge/plantuml/creole/AtomHorizontalTexts.java index b5f757fb8..251112365 100644 --- a/src/net/sourceforge/plantuml/creole/AtomHorizontalTexts.java +++ b/src/net/sourceforge/plantuml/creole/AtomHorizontalTexts.java @@ -43,7 +43,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class AtomHorizontalTexts implements Atom { +public class AtomHorizontalTexts extends AbstractAtom implements Atom { private final List all; public AtomHorizontalTexts(List texts) { diff --git a/src/net/sourceforge/plantuml/creole/AtomImg.java b/src/net/sourceforge/plantuml/creole/AtomImg.java index d2a882415..01c0fc603 100644 --- a/src/net/sourceforge/plantuml/creole/AtomImg.java +++ b/src/net/sourceforge/plantuml/creole/AtomImg.java @@ -62,7 +62,7 @@ import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImage; -public class AtomImg implements Atom { +public class AtomImg extends AbstractAtom implements Atom { private static final String DATA_IMAGE_PNG_BASE64 = "data:image/png;base64,"; private final BufferedImage image; diff --git a/src/net/sourceforge/plantuml/creole/AtomImgSvg.java b/src/net/sourceforge/plantuml/creole/AtomImgSvg.java index f12c14b71..e5e78774d 100644 --- a/src/net/sourceforge/plantuml/creole/AtomImgSvg.java +++ b/src/net/sourceforge/plantuml/creole/AtomImgSvg.java @@ -41,7 +41,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TileImageSvg; import net.sourceforge.plantuml.ugraphic.UGraphic; -public class AtomImgSvg implements Atom { +public class AtomImgSvg extends AbstractAtom implements Atom { private final TileImageSvg tileImageSvg; diff --git a/src/net/sourceforge/plantuml/creole/AtomMath.java b/src/net/sourceforge/plantuml/creole/AtomMath.java index e339a39b4..f386ef003 100644 --- a/src/net/sourceforge/plantuml/creole/AtomMath.java +++ b/src/net/sourceforge/plantuml/creole/AtomMath.java @@ -50,7 +50,7 @@ import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImage; import net.sourceforge.plantuml.ugraphic.UImageSvg; -public class AtomMath implements Atom { +public class AtomMath extends AbstractAtom implements Atom { private final double scale; private final ScientificEquationSafe math; diff --git a/src/net/sourceforge/plantuml/creole/AtomOpenIcon.java b/src/net/sourceforge/plantuml/creole/AtomOpenIcon.java index 94f7799eb..1f51ce092 100644 --- a/src/net/sourceforge/plantuml/creole/AtomOpenIcon.java +++ b/src/net/sourceforge/plantuml/creole/AtomOpenIcon.java @@ -46,7 +46,7 @@ import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.openiconic.OpenIcon; import net.sourceforge.plantuml.ugraphic.UGraphic; -public class AtomOpenIcon implements Atom { +public class AtomOpenIcon extends AbstractAtom implements Atom { private final OpenIcon openIcon; private final double factor; diff --git a/src/net/sourceforge/plantuml/creole/AtomSpace.java b/src/net/sourceforge/plantuml/creole/AtomSpace.java index 583adb30e..2f73c298b 100644 --- a/src/net/sourceforge/plantuml/creole/AtomSpace.java +++ b/src/net/sourceforge/plantuml/creole/AtomSpace.java @@ -41,7 +41,7 @@ import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; -public class AtomSpace implements Atom { +public class AtomSpace extends AbstractAtom implements Atom { private final double width; diff --git a/src/net/sourceforge/plantuml/creole/AtomSprite.java b/src/net/sourceforge/plantuml/creole/AtomSprite.java index ae4832a7b..9e09e7b2c 100644 --- a/src/net/sourceforge/plantuml/creole/AtomSprite.java +++ b/src/net/sourceforge/plantuml/creole/AtomSprite.java @@ -36,6 +36,8 @@ package net.sourceforge.plantuml.creole; import java.awt.geom.Dimension2D; +import java.util.Arrays; +import java.util.List; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -44,13 +46,18 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.sprite.Sprite; -public class AtomSprite implements Atom { +public class AtomSprite extends AbstractAtom implements Atom { private final Sprite sprite; private final double scale; private final Url url; private final HtmlColor color; + @Override + public List splitInTwo(StringBounder stringBounder, double width) { + return Arrays.asList((Atom) this); + } + public AtomSprite(HtmlColor newColor, double scale, FontConfiguration fontConfiguration, Sprite sprite, Url url) { this.scale = scale; this.sprite = sprite; diff --git a/src/net/sourceforge/plantuml/creole/AtomTable.java b/src/net/sourceforge/plantuml/creole/AtomTable.java index 3d11c02a7..6022d5a82 100644 --- a/src/net/sourceforge/plantuml/creole/AtomTable.java +++ b/src/net/sourceforge/plantuml/creole/AtomTable.java @@ -52,7 +52,7 @@ import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class AtomTable implements Atom { +public class AtomTable extends AbstractAtom implements Atom { class Line { private final List cells = new ArrayList(); diff --git a/src/net/sourceforge/plantuml/creole/AtomText.java b/src/net/sourceforge/plantuml/creole/AtomText.java index fd7e22db5..ef79f33af 100644 --- a/src/net/sourceforge/plantuml/creole/AtomText.java +++ b/src/net/sourceforge/plantuml/creole/AtomText.java @@ -67,7 +67,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.sprite.Sprite; import net.sourceforge.plantuml.utils.CharHidder; -public class AtomText implements Atom { +public class AtomText extends AbstractAtom implements Atom { interface DelayedDouble { public double getDouble(StringBounder stringBounder); @@ -142,10 +142,6 @@ public class AtomText implements Atom { return new AtomHorizontalTexts(result); } - // private static Atom createAtomTextOld(final String text, Url url, FontConfiguration fontConfiguration) { - // return new AtomText(text, fontConfiguration, url, ZERO, ZERO); - // } - public static AtomText createHeading(String text, FontConfiguration fontConfiguration, int order) { if (order == 0) { fontConfiguration = fontConfiguration.bigger(4).bold(); @@ -186,7 +182,6 @@ public class AtomText implements Atom { } this.marginLeft = marginLeft; this.marginRight = marginRight; - // this.text = StringUtils.showComparatorCharacters(StringUtils.manageBackslash(text)); this.text = StringUtils.manageTildeArobaseStart(StringUtils.manageUnicodeNotationUplus(StringUtils .manageAmpDiese(StringUtils.showComparatorCharacters(CharHidder.unhide(text))))); this.fontConfiguration = style; @@ -332,6 +327,27 @@ public class AtomText implements Atom { } + @Override + public List splitInTwo(StringBounder stringBounder, double width) { + final StringTokenizer st = new StringTokenizer(text, " ", true); + final StringBuilder tmp = new StringBuilder(); + while (st.hasMoreTokens()) { + final String token = st.nextToken(); + if (tmp.length() > 0 && getWidth(stringBounder, tmp.toString() + token) > width) { + final Atom part1 = new AtomText(tmp.toString(), fontConfiguration, url, marginLeft, marginRight); + String remain = text.substring(tmp.length()); + while (remain.startsWith(" ")) { + remain = remain.substring(1); + } + + final Atom part2 = new AtomText(remain, fontConfiguration, url, marginLeft, marginRight); + return Arrays.asList(part1, part2); + } + tmp.append(token); + } + return Collections.singletonList((Atom) this); + } + private List splitLong1(StringBounder stringBounder, double maxWidth, String add) { return Arrays.asList(add); } diff --git a/src/net/sourceforge/plantuml/creole/AtomTree.java b/src/net/sourceforge/plantuml/creole/AtomTree.java index af149e52b..73946c798 100644 --- a/src/net/sourceforge/plantuml/creole/AtomTree.java +++ b/src/net/sourceforge/plantuml/creole/AtomTree.java @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class AtomTree implements Atom { +public class AtomTree extends AbstractAtom implements Atom { private final HtmlColor lineColor; private final List cells = new ArrayList(); diff --git a/src/net/sourceforge/plantuml/creole/AtomVerticalTexts.java b/src/net/sourceforge/plantuml/creole/AtomVerticalTexts.java index 1ff73355c..649829540 100644 --- a/src/net/sourceforge/plantuml/creole/AtomVerticalTexts.java +++ b/src/net/sourceforge/plantuml/creole/AtomVerticalTexts.java @@ -43,7 +43,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class AtomVerticalTexts implements Atom { +public class AtomVerticalTexts extends AbstractAtom implements Atom { private final List all; public AtomVerticalTexts(List texts) { diff --git a/src/net/sourceforge/plantuml/creole/AtomWithMargin.java b/src/net/sourceforge/plantuml/creole/AtomWithMargin.java index f6345e83b..e4688c97d 100644 --- a/src/net/sourceforge/plantuml/creole/AtomWithMargin.java +++ b/src/net/sourceforge/plantuml/creole/AtomWithMargin.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -class AtomWithMargin implements Atom { +class AtomWithMargin extends AbstractAtom implements Atom { private final double marginY1; private final double marginY2; diff --git a/src/net/sourceforge/plantuml/creole/Bullet.java b/src/net/sourceforge/plantuml/creole/Bullet.java index 27b339fb6..40f2e404f 100644 --- a/src/net/sourceforge/plantuml/creole/Bullet.java +++ b/src/net/sourceforge/plantuml/creole/Bullet.java @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class Bullet implements Atom { +public class Bullet extends AbstractAtom implements Atom { private final FontConfiguration fontConfiguration; private final int order; diff --git a/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java b/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java index 9b6f1df4f..ed06413d4 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java +++ b/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java @@ -50,7 +50,7 @@ import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UHorizontalLine; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class CreoleHorizontalLine implements Atom { +public class CreoleHorizontalLine extends AbstractAtom implements Atom { private final FontConfiguration fontConfiguration; private final String line; diff --git a/src/net/sourceforge/plantuml/creole/Fission.java b/src/net/sourceforge/plantuml/creole/Fission.java index b4f04ce4c..78cd9ed98 100644 --- a/src/net/sourceforge/plantuml/creole/Fission.java +++ b/src/net/sourceforge/plantuml/creole/Fission.java @@ -59,7 +59,49 @@ public class Fission { } } + static private boolean NEW_MODE = true; + + public List getSplitted2(StringBounder stringBounder) { + final double valueMaxWidth = maxWidth.getMaxWidth(); + if (valueMaxWidth == 0) { + return Arrays.asList(stripe); + } + final List result = new ArrayList(); + StripeSimple current = new StripeSimple(stripe.getHeader()); + double remainingSpace = valueMaxWidth; + for (Atom atom : noHeader()) { + while (true) { + final List splitInTwo = atom.splitInTwo(stringBounder, remainingSpace); + final Atom part1 = splitInTwo.get(0); + final double widthPart1 = part1.calculateDimension(stringBounder).getWidth(); + current.addAtom(part1, widthPart1); + remainingSpace -= widthPart1; + if (remainingSpace <= 0) { + result.add(current); + current = new StripeSimple(blank(stripe.getHeader())); + remainingSpace = valueMaxWidth; + } + if (splitInTwo.size() == 1) { + break; + } + atom = splitInTwo.get(1); + if (remainingSpace < valueMaxWidth + && atom.calculateDimension(stringBounder).getWidth() > remainingSpace) { + result.add(current); + current = new StripeSimple(blank(stripe.getHeader())); + remainingSpace = valueMaxWidth; + } + } + } + if (remainingSpace < valueMaxWidth) { + result.add(current); + } + return Collections.unmodifiableList(result); + } + public List getSplitted(StringBounder stringBounder) { + if (NEW_MODE) + return getSplitted2(stringBounder); final double valueMaxWidth = maxWidth.getMaxWidth(); if (valueMaxWidth == 0) { return Arrays.asList(stripe); @@ -94,7 +136,7 @@ public class Fission { if (header == null) { return null; } - return new Atom() { + return new AbstractAtom() { public Dimension2D calculateDimension(StringBounder stringBounder) { return header.calculateDimension(stringBounder); diff --git a/src/net/sourceforge/plantuml/creole/PSystemCreole.java b/src/net/sourceforge/plantuml/creole/PSystemCreole.java index 9f9612fd7..b3c1c8842 100644 --- a/src/net/sourceforge/plantuml/creole/PSystemCreole.java +++ b/src/net/sourceforge/plantuml/creole/PSystemCreole.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.creole; -import java.awt.Font; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock1.java b/src/net/sourceforge/plantuml/creole/SheetBlock1.java index 7d43d0659..2fbae6928 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock1.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock1.java @@ -55,6 +55,10 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, Stencil { + public List splitInTwo(StringBounder stringBounder, double width) { + throw new UnsupportedOperationException(getClass().toString()); + } + private final Sheet sheet; private List stripes; private Map heights; diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock2.java b/src/net/sourceforge/plantuml/creole/SheetBlock2.java index 557a69a38..49587671e 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock2.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock2.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.creole; import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; +import java.util.List; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.InnerStrategy; @@ -48,6 +49,10 @@ import net.sourceforge.plantuml.ugraphic.UStroke; public class SheetBlock2 extends AbstractTextBlock implements TextBlock, Atom { + public List splitInTwo(StringBounder stringBounder, double width) { + throw new UnsupportedOperationException(getClass().toString()); + } + private final SheetBlock1 block; private final UStroke defaultStroke; private final Stencil stencil; diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java index 6e62f9229..b907c8a4f 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -537,9 +537,9 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, // public void hideOrShow(Stereotype stereotype, boolean show) { // if (show) { - // hiddenStereotype.remove(stereotype.getLabel(false)); + // hiddenStereotype.remove(stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); // } else { - // hiddenStereotype.add(stereotype.getLabel(false)); + // hiddenStereotype.add(stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); // } // } // diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java index 96a539a87..5a6cd61e6 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java @@ -43,13 +43,13 @@ import java.util.Iterator; import java.util.List; import net.sourceforge.plantuml.BackSlash; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; import net.sourceforge.plantuml.EmbeddedDiagram; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.LineLocationImpl; import net.sourceforge.plantuml.SpriteContainer; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -73,31 +73,60 @@ import net.sourceforge.plantuml.sequencediagram.MessageNumber; import net.sourceforge.plantuml.skin.VisibilityModifier; import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UStroke; -import net.sourceforge.plantuml.ugraphic.sprite.Sprite; public class Display implements Iterable { - private final List display; + private final List displayData; private final HorizontalAlignment naturalHorizontalAlignment; private final boolean isNull; private final CreoleMode defaultCreoleMode; public final static Display NULL = new Display(null, null, true, CreoleMode.FULL); + private void check() { +// if (displayData != null) +// for (CharSequence s : displayData) { +// if (s == null) { +// continue; +// } +// if (s instanceof String) { +// continue; +// } +// if (s instanceof Stereotype) { +// continue; +// } +// // if (s instanceof CharSequence2) { +// // continue; +// // } +// if (s instanceof MessageNumber) { +// continue; +// } +// if (s instanceof EmbeddedDiagram) { +// continue; +// } +// System.err.println("PB=" + s); +// System.err.println("PB=" + s.getClass()); +// for (int i = 0; i < 100; i++) +// Thread.dumpStack(); +// System.exit(0); +// } + } + public Display replaceBackslashT() { final Display result = new Display(this, defaultCreoleMode); - for (int i = 0; i < result.display.size(); i++) { - final CharSequence s = display.get(i); + for (int i = 0; i < result.displayData.size(); i++) { + final CharSequence s = displayData.get(i); if (s.toString().contains("\\t")) { - result.display.set(i, s.toString().replace("\\t", "\t")); + result.displayData.set(i, s.toString().replace("\\t", "\t")); } } + result.check(); return result; } public Display replace(String src, String dest) { final List newDisplay = new ArrayList(); - for (CharSequence cs : display) { + for (CharSequence cs : displayData) { if (cs.toString().contains(src)) { cs = cs.toString().replace(src, dest); } @@ -107,8 +136,8 @@ public class Display implements Iterable { } public boolean isWhite() { - return display == null || display.size() == 0 - || (display.size() == 1 && display.get(0).toString().matches("\\s*")); + return displayData == null || displayData.size() == 0 + || (displayData.size() == 1 && displayData.get(0).toString().matches("\\s*")); } public static Display empty() { @@ -119,6 +148,14 @@ public class Display implements Iterable { return create(Arrays.asList(s)); } + public static Display createFoo(List data) { + final List tmp = new ArrayList(); + for (StringLocated s : data) { + tmp.add(s.getString()); + } + return create(tmp); + } + public static Display create(Collection other) { return new Display(other, null, false, CreoleMode.FULL); } @@ -176,22 +213,25 @@ public class Display implements Iterable { private Display(Display other, CreoleMode mode) { this(other.naturalHorizontalAlignment, other.isNull, mode); - this.display.addAll(other.display); + this.displayData.addAll(other.displayData); + this.check(); } private Display(HorizontalAlignment naturalHorizontalAlignment, boolean isNull, CreoleMode defaultCreoleMode) { this.defaultCreoleMode = defaultCreoleMode; this.isNull = isNull; - this.display = isNull ? null : new ArrayList(); + this.displayData = isNull ? null : new ArrayList(); this.naturalHorizontalAlignment = isNull ? null : naturalHorizontalAlignment; + this.check(); } private Display(Collection other, HorizontalAlignment naturalHorizontalAlignment, boolean isNull, CreoleMode defaultCreoleMode) { this(naturalHorizontalAlignment, isNull, defaultCreoleMode); if (isNull == false) { - this.display.addAll(manageEmbeddedDiagrams(other)); + this.displayData.addAll(manageEmbeddedDiagrams(other)); } + this.check(); } private static List manageEmbeddedDiagrams(final Collection strings) { @@ -199,11 +239,17 @@ public class Display implements Iterable { final Iterator it = strings.iterator(); while (it.hasNext()) { CharSequence s = it.next(); + if (s instanceof StringLocated) { + s = ((StringLocated) s).getString(); + } if (s != null && StringUtils.trin(s.toString()).equals("{{")) { final List other = new ArrayList(); other.add("@startuml"); while (it.hasNext()) { - final CharSequence s2 = it.next(); + CharSequence s2 = it.next(); + if (s2 instanceof StringLocated) { + s2 = ((StringLocated) s2).getString(); + } if (s2 != null && StringUtils.trin(s2.toString()).equals("}}")) { break; } @@ -220,28 +266,24 @@ public class Display implements Iterable { public Display manageGuillemet() { final List result = new ArrayList(); boolean first = true; - for (CharSequence line : display) { + for (CharSequence line : displayData) { String lineString = line.toString(); if (first && VisibilityModifier.isVisibilityCharacter(line)) { lineString = lineString.substring(1).trim(); } - final String withGuillement = StringUtils.manageGuillemet(lineString); - // if (withGuillement.equals(lineString)) { - // result.add(lineString); - // } else { + final String withGuillement = Guillemet.GUILLEMET.manageGuillemet(lineString); result.add(withGuillement); - // } first = false; } return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); } public Display withPage(int page, int lastpage) { - if (display == null) { + if (displayData == null) { return this; } final List result = new ArrayList(); - for (CharSequence line : display) { + for (CharSequence line : displayData) { line = line.toString().replace("%page%", "" + page); line = line.toString().replace("%lastpage%", "" + lastpage); result.add(line); @@ -251,7 +293,7 @@ public class Display implements Iterable { public Display underlined() { final List result = new ArrayList(); - for (CharSequence line : display) { + for (CharSequence line : displayData) { result.add("" + line); } return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); @@ -264,61 +306,57 @@ public class Display implements Iterable { return new Display(this, mode); } - // private String asStringWithHiddenNewLine() { - // final StringBuilder sb = new StringBuilder(); - // for (int i = 0; i < display.size(); i++) { - // sb.append(display.get(i)); - // if (i < display.size() - 1) { - // sb.append(BackSlash.hiddenNewLine()); - // } - // } - // return sb.toString(); - // } - @Override public String toString() { if (isNull) { return "NULL"; } - return display.toString(); + return displayData.toString(); } @Override public int hashCode() { - return display.hashCode(); + return displayData.hashCode(); } @Override public boolean equals(Object other) { - return this.display.equals(((Display) other).display); + return this.displayData.equals(((Display) other).displayData); } public Display addAll(Display other) { final Display result = new Display(this, this.defaultCreoleMode); - result.display.addAll(other.display); + result.displayData.addAll(other.displayData); + result.check(); return result; } public Display addFirst(CharSequence s) { final Display result = new Display(this, this.defaultCreoleMode); - result.display.add(0, s); + result.displayData.add(0, s); + result.check(); return result; } public Display add(CharSequence s) { + if (s instanceof StringLocated) { + s = ((StringLocated) s).getString(); + } final Display result = new Display(this, this.defaultCreoleMode); - result.display.add(s); + result.displayData.add(s); + result.check(); return result; } public Display addGeneric(CharSequence s) { final Display result = new Display(this, this.defaultCreoleMode); - final int size = display.size(); + final int size = displayData.size(); if (size == 0) { - result.display.add("<" + s + ">"); + result.displayData.add("<" + s + ">"); } else { - result.display.set(size - 1, display.get(size - 1) + "<" + s + ">"); + result.displayData.set(size - 1, displayData.get(size - 1) + "<" + s + ">"); } + result.check(); return result; } @@ -326,32 +364,32 @@ public class Display implements Iterable { if (isNull) { return 0; } - return display.size(); + return displayData.size(); } public CharSequence get(int i) { - return display.get(i); + return displayData.get(i); } public Iterator iterator() { - return Collections.unmodifiableList(display).iterator(); + return Collections.unmodifiableList(displayData).iterator(); } public Display subList(int i, int size) { - return new Display(display.subList(i, size), this.naturalHorizontalAlignment, this.isNull, + return new Display(displayData.subList(i, size), this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); } public List as() { - return Collections.unmodifiableList(display); + return Collections.unmodifiableList(displayData); } - public List as2() { - final List result = new ArrayList(); + public List as2() { + final List result = new ArrayList(); LineLocationImpl location = new LineLocationImpl("inner", null); - for (CharSequence cs : display) { + for (CharSequence cs : displayData) { location = location.oneLineRead(); - result.add(new CharSequence2Impl(cs, location)); + result.add(new StringLocated(cs.toString(), location)); } return Collections.unmodifiableList(result); } @@ -374,17 +412,17 @@ public class Display implements Iterable { final List result = new ArrayList(); Display pending = new Display(this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); result.add(pending); - for (CharSequence line : display) { + for (CharSequence line : displayData) { final Matcher2 m = separator.matcher(line); if (m.find()) { final CharSequence s1 = line.subSequence(0, m.start()); - pending.display.add(s1); + pending.displayData.add(s1); final CharSequence s2 = line.subSequence(m.end(), line.length()); pending = new Display(this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode); result.add(pending); - pending.display.add(s2); + pending.displayData.add(s2); } else { - pending.display.add(line); + pending.displayData.add(line); } } return Collections.unmodifiableList(result); @@ -484,7 +522,7 @@ public class Display implements Iterable { circledCharacter = stereotype.getSprite(spriteContainer); } if (circledCharacter != null) { - if (stereotype.getLabel(false) == null) { + if (stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { return new TextBlockSprited(circledCharacter, this.subList(1, this.size()), fontConfiguration, horizontalAlignment, spriteContainer); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java b/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java index afd8d5ea3..9200efaa2 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java @@ -35,6 +35,8 @@ */ package net.sourceforge.plantuml.cucadiagram; +import net.sourceforge.plantuml.Guillemet; + public class EntityGenderUtils { static public EntityGender byEntityType(final LeafType type) { @@ -59,7 +61,7 @@ public class EntityGenderUtils { if (test.getStereotype() == null) { return false; } - return stereotype.equals(test.getStereotype().getLabel(false)); + return stereotype.equals(test.getStereotype().getLabel(Guillemet.DOUBLE_COMPARATOR)); } }; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java index d1d7d0d18..84dc2c216 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Link.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -118,9 +118,6 @@ public class Link extends WithLinkType implements Hideable, Removeable { this.type = type; if (Display.isNull(label)) { this.label = Display.NULL; - // } else if (doWeHaveToRemoveUrlAtStart(label)) { - // this.url = label.initUrl(); - // this.label = label.removeHeadingUrl(url).manageGuillemet(); } else { this.label = label.manageGuillemet(); if (VisibilityModifier.isVisibilityCharacter(label.get(0))) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java index 642f67ce9..d6257f599 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.cucadiagram; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -85,9 +86,9 @@ public class MemberImpl implements Member { if (VisibilityModifier.isVisibilityCharacter(displayClean)) { visibilityModifier = VisibilityModifier.getVisibilityModifier(displayClean, isMethod == false); - this.display = StringUtils.trin(StringUtils.manageGuillemet(displayClean.substring(1))); + this.display = StringUtils.trin(Guillemet.GUILLEMET.manageGuillemet(displayClean.substring(1))); } else { - this.display = StringUtils.manageGuillemet(displayClean); + this.display = Guillemet.GUILLEMET.manageGuillemet(displayClean); visibilityModifier = null; } } else { @@ -95,7 +96,7 @@ public class MemberImpl implements Member { this.visibilityModifier = null; this.abstractModifier = false; tmpDisplay = StringUtils.trin(tmpDisplay); - this.display = tmpDisplay.length() == 0 ? " " : StringUtils.manageGuillemet(StringUtils.trin(tmpDisplay)); + this.display = tmpDisplay.length() == 0 ? " " : Guillemet.GUILLEMET.manageGuillemet(StringUtils.trin(tmpDisplay)); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index e00b84997..f09d2f339 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -42,6 +42,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.SpriteContainer; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; @@ -98,7 +99,7 @@ public class Stereotype implements CharSequence { public Stereotype(String label, double radius, UFont circledFont, IHtmlColorSet htmlColorSet) { this(label, radius, circledFont, true, htmlColorSet); } - + public Stereotype(String label, boolean automaticPackageStyle) { this.automaticPackageStyle = automaticPackageStyle; this.label = label; @@ -129,7 +130,7 @@ public class Stereotype implements CharSequence { final StringBuilder tmpLabel = new StringBuilder(); - final List list = cutLabels(label, false); + final List list = cutLabels(label, Guillemet.DOUBLE_COMPARATOR); for (String local : list) { final RegexResult mCircleChar = circleChar.matcher(local); final RegexResult mCircleSprite = circleSprite.matcher(local); @@ -169,7 +170,6 @@ public class Stereotype implements CharSequence { this(label, true); } - public HtmlColor getHtmlColor() { return htmlColor; } @@ -240,35 +240,28 @@ public class Stereotype implements CharSequence { return circledFont; } - public String getLabel(boolean withGuillement) { + public String getLabel(Guillemet guillemet) { assert label == null || label.length() > 0; if (isWithOOSymbol()) { return null; } - if (withGuillement) { - return StringUtils.manageGuillemet(label); - } - return label; + return guillemet.manageGuillemet(label); } - public List getLabels(boolean useGuillemet) { - final String labelLocal = getLabel(false); + public List getLabels(Guillemet guillemet) { + final String labelLocal = getLabel(Guillemet.DOUBLE_COMPARATOR); if (labelLocal == null) { return null; } - return cutLabels(labelLocal, useGuillemet); + return cutLabels(labelLocal, guillemet); } - private static List cutLabels(final String label, boolean useGuillemet) { + private static List cutLabels(final String label, Guillemet guillemet) { final List result = new ArrayList(); final Pattern2 p = MyPattern.cmpile("\\<\\<.*?\\>\\>"); final Matcher2 m = p.matcher(label); while (m.find()) { - if (useGuillemet) { - result.add(StringUtils.manageGuillemetStrict(m.group())); - } else { - result.add(m.group()); - } + result.add(guillemet.manageGuillemetStrict(m.group())); } return Collections.unmodifiableList(result); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java index 9c74af904..8fe64afda 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java @@ -54,7 +54,6 @@ import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.EntityPortion; import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Member; import net.sourceforge.plantuml.cucadiagram.PortionShower; diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java index 42a7f95dc..e870ebda0 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java @@ -55,7 +55,6 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LongCode; -import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.skin.VisibilityModifier; public class EntityFactory { diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index bbd6b3e0d..0a3dfcbc3 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -46,6 +46,7 @@ import java.util.Map; import java.util.Set; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; @@ -66,7 +67,6 @@ import net.sourceforge.plantuml.cucadiagram.Stereotag; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.Neighborhood; import net.sourceforge.plantuml.graphic.FontConfiguration; -import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.USymbol; import net.sourceforge.plantuml.graphic.color.ColorType; @@ -312,7 +312,7 @@ final class EntityImpl implements ILeaf, IGroup { if (stereotype == null) { return EntityPosition.NORMAL; } - return EntityPosition.fromStereotype(stereotype.getLabel(false)); + return EntityPosition.fromStereotype(stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR)); } diff --git a/src/net/sourceforge/plantuml/dedication/QBlocks.java b/src/net/sourceforge/plantuml/dedication/QBlocks.java index f02cd4994..f00888ffd 100644 --- a/src/net/sourceforge/plantuml/dedication/QBlocks.java +++ b/src/net/sourceforge/plantuml/dedication/QBlocks.java @@ -42,8 +42,6 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.code.AsciiEncoder; - public class QBlocks { private final List all = new ArrayList(); diff --git a/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java b/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java index e51ba29f9..8a77e238d 100644 --- a/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java +++ b/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.descdiagram; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -79,7 +80,7 @@ public class CommandCreateDomain extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(DescriptionDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLocation location, RegexResult arg) { String type = arg.get("TYPE", 0); String display = arg.getLazzy("DISPLAY", 0); String code = arg.getLazzy("CODE", 0); diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java index 6e800f630..d78298089 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java @@ -40,6 +40,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; @@ -76,10 +77,10 @@ public class EntityImageDesignedDomain extends AbstractEntityImage { this.name = TextBlockUtils.withMargin( entity.getDisplay().create(new FontConfiguration(getSkinParam(), FontParam.DESIGNED_DOMAIN, stereotype), HorizontalAlignment.CENTER, skinParam), 2, 2); - if (stereotype == null || stereotype.getLabel(false) == null) { + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { this.stereo = null; } else { - this.stereo = Display.create(stereotype.getLabels(skinParam.useGuillemet())).create( + this.stereo = Display.create(stereotype.getLabels(skinParam.guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.DESIGNED_DOMAIN_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); } diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java index 87f75aab2..117995f7f 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java @@ -40,6 +40,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; @@ -78,10 +79,10 @@ public class EntityImageDomain extends AbstractEntityImage { FontConfiguration fc = new FontConfiguration(getSkinParam(), FontParam.DESIGNED_DOMAIN, stereotype); this.name = TextBlockUtils.withMargin(entity.getDisplay().create(fc, HorizontalAlignment.CENTER, skinParam), 2, 2); - if (stereotype == null || stereotype.getLabel(false) == null) { + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { this.stereo = null; } else { - this.stereo = Display.create(stereotype.getLabels(skinParam.useGuillemet())).create( + this.stereo = Display.create(stereotype.getLabels(skinParam.guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.DESIGNED_DOMAIN_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); } diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java index 329ffbdb1..bb71a6594 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java @@ -40,6 +40,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; @@ -76,10 +77,10 @@ public class EntityImageMachine extends AbstractEntityImage { this.name = TextBlockUtils.withMargin( entity.getDisplay().create(new FontConfiguration(getSkinParam(), FontParam.MACHINE, stereotype), HorizontalAlignment.CENTER, skinParam), 2, 2); - if (stereotype == null || stereotype.getLabel(false) == null) { + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { this.stereo = null; } else { - this.stereo = Display.create(stereotype.getLabels(skinParam.useGuillemet())).create( + this.stereo = Display.create(stereotype.getLabels(skinParam.guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.MACHINE_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); } diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java index a0c3913ee..d87d9fe5d 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java @@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; @@ -81,10 +82,10 @@ public class EntityImageRequirement extends AbstractEntityImage { final TextBlock tmp = new BodyEnhanced(entity.getDisplay(), FontParam.REQUIREMENT, skinParam, HorizontalAlignment.CENTER, stereotype, true, false, entity); - if (stereotype == null || stereotype.getLabel(false) == null) { + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { this.desc = tmp; } else { - final TextBlock stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().useGuillemet())) + final TextBlock stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())) .create(new FontConfiguration(getSkinParam(), FontParam.REQUIREMENT_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); this.desc = TextBlockUtils.mergeTB(stereo, tmp, HorizontalAlignment.CENTER); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java index b5947aa2b..f52e18381 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.descdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -94,7 +95,7 @@ public class CommandArchimate extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(DescriptionDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLocation location, RegexResult arg) { final String codeRaw = arg.getLazzy("CODE", 0); final Code code = Code.of(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeRaw)); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java index 736517ad3..054c780a7 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java @@ -91,7 +91,7 @@ public class CommandArchimateMultilines extends CommandMultilines2 lineLast = StringUtils.getSplit(MyPattern.cmpile(getPatternEnd()), lines.getLast499() - .toString()); + .getString()); lines = lines.subExtract(1, 1); Display display = lines.toDisplay(); final String descStart = line0.get("DESC", 0); @@ -162,7 +162,7 @@ public class CommandCreateElementMultilines extends CommandMultilines2 { } @Override - protected CommandExecutionResult executeArg(DescriptionDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLocation location, RegexResult arg) { final Code ent1 = Code.of(arg.get("ENT1", 0)); final Code ent2 = Code.of(arg.get("ENT2", 0)); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandNewpage.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandNewpage.java index b92f177ea..da931b3c0 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandNewpage.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandNewpage.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.descdiagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.NewpagedDiagram; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -60,7 +61,7 @@ public class CommandNewpage extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(UmlDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(UmlDiagram diagram, LineLocation location, RegexResult arg) { final int dpi = diagram.getSkinParam().getDpi(); final UmlDiagram emptyDiagram = (UmlDiagram) factory.createEmptyDiagram(); if (dpi != 96) { diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java index e5100b76f..13e50726e 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.descdiagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -110,7 +111,7 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2 clDiagram = Class.forName("org.stathissideris.ascii2image.graphics.Diagram"); + clDiagram.getConstructor(grid.getClass(), options.getClass(), processingOptions.getClass()).newInstance( + grid, options, processingOptions); + final Object diagram = clDiagram.getConstructor(grid.getClass(), options.getClass(), + processingOptions.getClass()).newInstance(grid, options, processingOptions); + + // final BitmapRenderer bitmapRenderer = new BitmapRenderer(); + final Object bitmapRenderer = Class.forName("org.stathissideris.ascii2image.graphics.BitmapRenderer") + .newInstance(); + + // final BufferedImage image = (BufferedImage) bitmapRenderer.renderToImage(diagram, renderingOptions); + final Method renderToImage = bitmapRenderer.getClass().getMethod("renderToImage", diagram.getClass(), + renderingOptions.getClass()); + final BufferedImage image = (BufferedImage) renderToImage.invoke(bitmapRenderer, diagram, renderingOptions); + + ImageIO.write(image, "png", os); + final int width = image.getWidth(); + final int height = image.getHeight(); + return new ImageDataSimple(width, height); + } catch (Exception e) { + e.printStackTrace(); + } + return null; } diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index e05cde229..dc5121d98 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -70,23 +70,23 @@ public class PSystemDonors extends AbstractPSystem { private static final int COLS = 6; private static final int FREE_LINES = 6; - - public static final String DONORS = "6-i802mER3hSGmjfrjohVvkCORGYHh0yJoWE0ujukXiGVu1xfyVzHlgBw4htlcb6jFNQmfn110UWdZZ_" - + "PcXvrr_ZDrzV9MDSrT8L9a3W7UFIll6NjuMOAhRVCg6zl_suK8UqLWYkm4tb_F_tAc1EA22BiodcdmEq" - + "1guzkkpTJwszbbxi_OAsG6CQ_TYoKfRQXf6lQs0DFOsDunrHiYh6wY95MnjRW9PFt4ZKHky4dqYj_gCM" - + "gKbhTWtfBW74CbB4chTb2_jE3f_2m8b0BJiK8CA1X4DsaOExFf400fKqQiH6CHlhAJxoH0mHUgYm2__8" - + "IV7PGvP76JeGgEq60bg_GH20Pr52YSqs7mRaxc4j2Xeir9cvqIFTNmnEkT9fk9JiK8kW5b0586-2BkXr" - + "zPbBd6LiYXAUl8NnQei1SfRr0JYUhEZhBeM1ydltm4oOouLgwo7CATSnVdLqm4yD6TdxJUlZcCL4p6zp" - + "GOOlBC3v0kYbrb0n_huv7op4GsXCgGivSGuVxxC8X5MMWaLkOefhhfzq6Pirn7phmc9xYRxE36KPHk1A" - + "nHx0HxJSFgZp1NJLKFyyvAhh-1Isnct1tZ9yEcdE5V_lkYMPKRg0Dfhm8RfIecJf1QjyCIaYS0NGbm4F" - + "IN8ZLLycZ_9b-P1utvy4yUQ40v7Qh61_KCveN7AOGhomrf4gLW3JNQ9U23Hkf1j-dO3U1Yg7o0Xt_Puc" - + "x66JnjIvmHMtko7685-au-MB7fkvP5ngw9PfiskdzWEE0jo1Dychxitagm2MejuTYwNnD0RSDSnf1kay" - + "8kzxsf8UbpfAoxBVugekyMnk1tyUEhtWB1PDCQED7p8d51-JKLEt6CzJWyPlayWwxH56dGqC3m7XG8Pb" - + "V0fOLqoUgUG8WSfmXaCk9adejCuhTfc0knUgOUspFNKj8TPJLny3rSQFE1iPKCawuGJY6Eu6EsFZAB9V" - + "Dk-LKJVrRGY6Bw10318Sf4BPHWWgm-OKCgJtISzadEJplBJBGhwDRpPUOIXyWaHtpJROPGhnA97Tg1i0" - + "N1-sIhpuCJ42-1bllu6URQw3dd-ZfvN50Mmg2G5JOMk7VmdsLAwRDOdr5hrkQ-rjsVdpxtLa6gTatyOg" - + "0VGOPDD_4GHn4dMjy1RquuBF4cWiP0HsTR1jAxU67WSO5BIfPPghjcL6V3hBolNK3e_q3-N-xv194DZD" - + "9oIzE0ILeqy9LcjlTQKoqJxznk8Y1ul_4rLQChdAkieP2IHU0000"; + + 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"; @Override final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed) diff --git a/src/net/sourceforge/plantuml/eps/EpsGraphics.java b/src/net/sourceforge/plantuml/eps/EpsGraphics.java index 54d9576b9..646a3733a 100644 --- a/src/net/sourceforge/plantuml/eps/EpsGraphics.java +++ b/src/net/sourceforge/plantuml/eps/EpsGraphics.java @@ -49,6 +49,7 @@ import net.sourceforge.plantuml.ugraphic.ShadowManager; import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.USegment; import net.sourceforge.plantuml.ugraphic.USegmentType; +import net.sourceforge.plantuml.utils.MathUtils; import net.sourceforge.plantuml.version.Version; public class EpsGraphics { @@ -63,7 +64,7 @@ public class EpsGraphics { private Color color = Color.BLACK; private Color fillcolor = Color.BLACK; - private String strokeWidth = "1"; + private String strokeWidth = format(1); // private String strokeDasharray = null; private final PostScriptCommandMacro setcolorgradient = new PostScriptCommandMacro("setcolorgradient"); @@ -132,7 +133,7 @@ public class EpsGraphics { header.append("%%EndComments\n\n"); header.append("gsave\n"); header.append("0 " + maxY + " translate\n"); - header.append("1 -1 scale\n"); + header.append(".01 -.01 scale\n"); if (setcolorgradientUsed) { header.append(setcolorgradient.getPostStringDefinition()); @@ -182,9 +183,9 @@ public class EpsGraphics { this.fillcolor = c; } - public final void setStrokeWidth(String strokeWidth, double dashVisible, double dashSpace) { + public final void setStrokeWidth(double strokeWidth, double dashVisible, double dashSpace) { checkCloseDone(); - this.strokeWidth = strokeWidth; + this.strokeWidth = format(strokeWidth); this.dashVisible = dashVisible; this.dashSpace = dashSpace; } @@ -278,7 +279,7 @@ public class EpsGraphics { } else if (type == USegmentType.SEG_CLOSE) { // Nothing } else { - Log.println("unknown " + seg); + Log.println("unknown1 " + seg); } } append("closepath eofill", true); @@ -302,7 +303,7 @@ public class EpsGraphics { } else if (type == USegmentType.SEG_CLOSE) { // Nothing } else { - Log.println("unknown " + seg); + Log.println("unknown2 " + seg); } } append("stroke", true); @@ -453,7 +454,8 @@ public class EpsGraphics { if (dashSpace != 0 && dashVisible != 0) { append("[" + (int) dashSpace + " " + (int) dashVisible + "] 0 setdash", true); } - append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " " + format((rx + ry) / 2) + final double round = MathUtils.min((rx + ry) / 2, width / 2, height / 2); + append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " " + format(round) + " roundrect", true); roundrectUsed = true; } @@ -541,7 +543,7 @@ public class EpsGraphics { final double r = c.getRed() / 255.0; final double g = c.getGreen() / 255.0; final double b = c.getBlue() / 255.0; - append(format(r) + " " + format(g) + " " + format(b) + " setrgbcolor", true); + append(formatSimple2(r) + " " + formatSimple2(g) + " " + formatSimple2(b) + " setrgbcolor", true); } protected void appendColorShort(Color c) { @@ -551,10 +553,17 @@ public class EpsGraphics { final double r = c.getRed() / 255.0; final double g = c.getGreen() / 255.0; final double b = c.getBlue() / 255.0; - append(format(r) + " " + format(g) + " " + format(b), true); + append(formatSimple2(r) + " " + formatSimple2(g) + " " + formatSimple2(b), true); } - public static String format(double x) { + static String format(double x) { + if (x == 0) { + return "0"; + } + return Long.toString((long) (x * 100)); + } + + public static String formatSimple4(double x) { if (x == 0) { return "0"; } @@ -566,6 +575,18 @@ public class EpsGraphics { return s; } + private static String formatSimple2(double x) { + if (x == 0) { + return "0"; + } + String s = String.format(Locale.US, "%1.2f", x); + s = s.replaceAll("(\\.\\d*?)0+$", "$1"); + if (s.endsWith(".")) { + s = s.substring(0, s.length() - 1); + } + return s; + } + protected void append(String s, boolean checkConsistence) { if (checkConsistence && s.indexOf(" ") != -1) { throw new IllegalArgumentException(s); diff --git a/src/net/sourceforge/plantuml/evalex/AbstractOperator.java b/src/net/sourceforge/plantuml/evalex/AbstractOperator.java index 6e526b167..4b8a0be05 100644 --- a/src/net/sourceforge/plantuml/evalex/AbstractOperator.java +++ b/src/net/sourceforge/plantuml/evalex/AbstractOperator.java @@ -26,8 +26,6 @@ */ package net.sourceforge.plantuml.evalex; -import java.math.BigDecimal; - import net.sourceforge.plantuml.evalex.Expression.LazyNumber; /** diff --git a/src/net/sourceforge/plantuml/flowdiagram/ActivityBox.java b/src/net/sourceforge/plantuml/flowdiagram/ActivityBox.java index 0c1c1d274..343d07f4a 100644 --- a/src/net/sourceforge/plantuml/flowdiagram/ActivityBox.java +++ b/src/net/sourceforge/plantuml/flowdiagram/ActivityBox.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.flowdiagram; -import java.awt.Font; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.Dimension2DDouble; diff --git a/src/net/sourceforge/plantuml/flowdiagram/CommandLineSimple.java b/src/net/sourceforge/plantuml/flowdiagram/CommandLineSimple.java index 478aada3e..983c79c03 100644 --- a/src/net/sourceforge/plantuml/flowdiagram/CommandLineSimple.java +++ b/src/net/sourceforge/plantuml/flowdiagram/CommandLineSimple.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.flowdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandLineSimple extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(FlowDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(FlowDiagram diagram, LineLocation location, RegexResult arg) { final String idDest = arg.get("ID_DEST", 0); final String label = arg.get("LABEL", 0); final String orientationString = arg.get("ORIENTATION", 0); diff --git a/src/net/sourceforge/plantuml/flowdiagram/CommandLink.java b/src/net/sourceforge/plantuml/flowdiagram/CommandLink.java index 3ef449f01..2a81fdb01 100644 --- a/src/net/sourceforge/plantuml/flowdiagram/CommandLink.java +++ b/src/net/sourceforge/plantuml/flowdiagram/CommandLink.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.flowdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandLink extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(FlowDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(FlowDiagram system, LineLocation location, RegexResult arg) { final String idDest = arg.get("ID_DEST", 0); final String orientationString = arg.get("ORIENTATION", 0); TileGeometry orientation = TileGeometry.SOUTH; diff --git a/src/net/sourceforge/plantuml/ftp/FtpConnexion.java b/src/net/sourceforge/plantuml/ftp/FtpConnexion.java index d549eb7ed..25d236cdc 100644 --- a/src/net/sourceforge/plantuml/ftp/FtpConnexion.java +++ b/src/net/sourceforge/plantuml/ftp/FtpConnexion.java @@ -193,9 +193,15 @@ public class FtpConnexion { } public synchronized void delete(String fileName) { - incoming.remove(fileName); - outgoing.remove(fileName); - futureOutgoing.add(fileName); + if (fileName.contains("*")) { + incoming.clear(); + outgoing.clear(); + futureOutgoing.clear(); + } else { + incoming.remove(fileName); + outgoing.remove(fileName); + futureOutgoing.add(fileName); + } } public void setFileFormat(FileFormat fileFormat) { diff --git a/src/net/sourceforge/plantuml/golem/Tile.java b/src/net/sourceforge/plantuml/golem/Tile.java index e9d46d386..91edc23cd 100644 --- a/src/net/sourceforge/plantuml/golem/Tile.java +++ b/src/net/sourceforge/plantuml/golem/Tile.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.golem; -import java.awt.Font; import java.awt.geom.Dimension2D; import java.util.Collections; import java.util.EnumMap; diff --git a/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java b/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java index 88c98124d..52d6c5c57 100644 --- a/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java +++ b/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.graph; -import java.awt.Font; import java.awt.Graphics2D; import java.awt.geom.Dimension2D; diff --git a/src/net/sourceforge/plantuml/graphic/CoordinateChange.java b/src/net/sourceforge/plantuml/graphic/CoordinateChange.java new file mode 100644 index 000000000..a7f2493f1 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/CoordinateChange.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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.Point2D; + +class CoordinateChange { + + private final double x1; + private final double y1; + private final double x2; + private final double y2; + + private final double vect_u_x; + private final double vect_u_y; + private final double vect_v_x; + private final double vect_v_y; + private final double len; + + public CoordinateChange(Point2D p1, Point2D p2) { + this(p1.getX(), p1.getY(), p2.getX(), p2.getY()); + } + + public CoordinateChange(double x1, double y1, double x2, double y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + this.len = Point2D.distance(x1, y1, x2, y2); + if (this.len == 0) { + throw new IllegalArgumentException(); + } + + this.vect_u_x = (x2 - x1) / len; + this.vect_u_y = (y2 - y1) / len; + + this.vect_v_x = -this.vect_u_y; + this.vect_v_y = this.vect_u_x; + + } + + public Point2D getTrueCoordinate(double a, double b) { + final double x = a * vect_u_x + b * vect_v_x; + final double y = a * vect_u_y + b * vect_v_y; + return new Point2D.Double(x1 + x, y1 + y); + } + + public final double getLength() { + return len; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/HtmlColorMiddle.java b/src/net/sourceforge/plantuml/graphic/HtmlColorMiddle.java new file mode 100644 index 000000000..27b386821 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/HtmlColorMiddle.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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.Color; + +import net.sourceforge.plantuml.ugraphic.ColorMapper; + +public class HtmlColorMiddle implements HtmlColor { + + private final HtmlColor c1; + private final HtmlColor c2; + + public HtmlColorMiddle(HtmlColor c1, HtmlColor c2) { + this.c1 = c1; + this.c2 = c2; + } + + public Color getMappedColor(ColorMapper colorMapper) { + final Color cc1 = colorMapper.getMappedColor(c1); + final Color cc2 = colorMapper.getMappedColor(c2); + final int r1 = cc1.getRed(); + final int g1 = cc1.getGreen(); + final int b1 = cc1.getBlue(); + final int r2 = cc2.getRed(); + final int g2 = cc2.getGreen(); + final int b2 = cc2.getBlue(); + + final int r = (r1 + r2) / 2; + final int g = (g1 + g2) / 2; + final int b = (b1 + b2) / 2; + return new Color(r, g, b); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/SkinParameter.java b/src/net/sourceforge/plantuml/graphic/SkinParameter.java index dc940df02..d27491d01 100644 --- a/src/net/sourceforge/plantuml/graphic/SkinParameter.java +++ b/src/net/sourceforge/plantuml/graphic/SkinParameter.java @@ -118,6 +118,9 @@ public class SkinParameter { public static final SkinParameter INTERFACE = new SkinParameter("INTERFACE", ColorParam.interfaceBackground, ColorParam.interfaceBorder, FontParam.INTERFACE, FontParam.INTERFACE_STEREOTYPE); + public static final SkinParameter PARTICIPANT = new SkinParameter("PARTICIPANT", ColorParam.participantBackground, + ColorParam.participantBorder, FontParam.PARTICIPANT, FontParam.PARTICIPANT_STEREOTYPE); + private final ColorParam colorParamBorder; private final ColorParam colorParamBack; private final FontParam fontParam; diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java b/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java index a0c3d3229..16e2d4c1e 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java @@ -43,6 +43,7 @@ import java.util.StringTokenizer; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.EmbeddedDiagram; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.SpriteContainer; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.cucadiagram.Display; @@ -158,9 +159,9 @@ public class TextBlockSimple extends AbstractTextBlock implements TextBlock { private List createLinesForStereotype(FontConfiguration fontConfiguration, Stereotype s, HorizontalAlignment horizontalAlignment, SpriteContainer spriteContainer) { - assert s.getLabel(false) != null; + assert s.getLabel(Guillemet.DOUBLE_COMPARATOR) != null; final List result = new ArrayList(); - for (String st : s.getLabels(spriteContainer.useGuillemet())) { + for (String st : s.getLabels(spriteContainer.guillemet())) { result.add(new SingleLine(st, fontConfiguration, horizontalAlignment, spriteContainer)); } return Collections.unmodifiableList(result); diff --git a/src/net/sourceforge/plantuml/graphic/USymbolCloud.java b/src/net/sourceforge/plantuml/graphic/USymbolCloud.java index 10ef5e500..670e49794 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolCloud.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolCloud.java @@ -36,6 +36,10 @@ package net.sourceforge.plantuml.graphic; import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -43,9 +47,16 @@ import net.sourceforge.plantuml.ugraphic.UGraphicStencil; import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; +// https://stackoverflow.com/questions/39552127/algorithm-for-drawing-random-comic-style-clouds +// http://martin-oehm.de/data/cloud.html +// https://stackoverflow.com/questions/34623855/what-is-the-algorithm-behind-the-pdf-cloud-annotation +// https://stackoverflow.com/questions/3177121/how-do-i-paint-clouds class USymbolCloud extends USymbol { + private final static boolean NEW = true; + private final static boolean DEBUG = false; + @Override public SkinParameter getSkinParameter() { return SkinParameter.CLOUD; @@ -54,12 +65,124 @@ class USymbolCloud extends USymbol { private void drawCloud(UGraphic ug, double width, double height, boolean shadowing) { final UPath shape = getSpecificFrontierForCloud(width, height); if (shadowing) { - shape.setDeltaShadow(3.0); + // shape.setDeltaShadow(3.0); } - ug.apply(new UTranslate(3, -3)).draw(shape); + ug.apply(new UTranslate(0, 0)).draw(shape); + } + + private UPath getSpecificFrontierForCloudNew(double width, double height) { + final Random rnd = new Random((long) width + 7919L * (long) height); + final List points = new ArrayList(); + + double bubbleSize = 11; + if (Math.max(width, height) / bubbleSize > 16) { + bubbleSize = Math.max(width, height) / 16; + } + + final double margin1 = 8; + + final Point2D.Double pointA = new Point2D.Double(margin1, margin1); + final Point2D.Double pointB = new Point2D.Double(width - margin1, margin1); + final Point2D.Double pointC = new Point2D.Double(width - margin1, height - margin1); + final Point2D.Double pointD = new Point2D.Double(margin1, height - margin1); + + if (width > 100 && height > 100) { + complex(rnd, points, bubbleSize, pointA, pointB, pointC, pointD); + } else { + simple(rnd, points, bubbleSize, pointA, pointB, pointC, pointD); + } + + points.add(points.get(0)); + + final UPath result = new UPath(); + result.moveTo(points.get(0)); + for (int i = 0; i < points.size() - 1; i++) { + if (DEBUG) { + result.lineTo(points.get(i + 1)); + } else { + addCurve(rnd, result, points.get(i), points.get(i + 1)); + } + } + return result; + + } + + private void complex(final Random rnd, final List points, double bubbleSize, final Point2D.Double pointA, + final Point2D.Double pointB, final Point2D.Double pointC, final Point2D.Double pointD) { + final double margin2 = 7; + specialLine(bubbleSize, rnd, points, mvX(pointA, margin2), mvX(pointB, -margin2)); + points.add(mvY(pointB, margin2)); + specialLine(bubbleSize, rnd, points, mvY(pointB, margin2), mvY(pointC, -margin2)); + points.add(mvX(pointC, -margin2)); + specialLine(bubbleSize, rnd, points, mvX(pointC, -margin2), mvX(pointD, margin2)); + points.add(mvY(pointD, -margin2)); + specialLine(bubbleSize, rnd, points, mvY(pointD, -margin2), mvY(pointA, margin2)); + points.add(mvX(pointA, margin2)); + } + + private void simple(final Random rnd, final List points, double bubbleSize, final Point2D.Double pointA, + final Point2D.Double pointB, final Point2D.Double pointC, final Point2D.Double pointD) { + specialLine(bubbleSize, rnd, points, pointA, pointB); + specialLine(bubbleSize, rnd, points, pointB, pointC); + specialLine(bubbleSize, rnd, points, pointC, pointD); + specialLine(bubbleSize, rnd, points, pointD, pointA); + } + + private static Point2D mvX(Point2D pt, double dx) { + return new Point2D.Double(pt.getX() + dx, pt.getY()); + } + + private static Point2D mvY(Point2D pt, double dy) { + return new Point2D.Double(pt.getX(), pt.getY() + dy); + } + + private void specialLine(double bubbleSize, Random rnd, List points, Point2D p1, Point2D p2) { + final CoordinateChange change = new CoordinateChange(p1, p2); + final double length = change.getLength(); + final Point2D middle = change.getTrueCoordinate(length / 2, -rnd(rnd, 1, 1 + Math.min(12, bubbleSize * 0.8))); + // final Point2D middle = change.getTrueCoordinate(length / 2, -13); + if (DEBUG) { + points.add(middle); + points.add(p2); + } else { + bubbleLine(rnd, points, p1, middle, bubbleSize); + bubbleLine(rnd, points, middle, p2, bubbleSize); + } + } + + private void bubbleLine(Random rnd, List points, Point2D p1, Point2D p2, double bubbleSize) { + final CoordinateChange change = new CoordinateChange(p1, p2); + final double length = change.getLength(); + final int nb = (int) (length / bubbleSize); + for (int i = 0; i < nb; i++) { + points.add(rnd(rnd, change.getTrueCoordinate(i * length / nb, 0), bubbleSize * .2)); + } + } + + private void addCurve(Random rnd, UPath path, Point2D p1, Point2D p2) { + final CoordinateChange change = new CoordinateChange(p1, p2); + final double length = change.getLength(); + final double coef = rnd(rnd, .25, .35); + final Point2D middle = change.getTrueCoordinate(length * coef, -length * rnd(rnd, .4, .55)); + final Point2D middle2 = change.getTrueCoordinate(length * (1 - coef), -length * rnd(rnd, .4, .55)); + path.cubicTo(middle, middle2, p2); + + } + + static private double rnd(Random rnd, double a, double b) { + return rnd.nextDouble() * (b - a) + a; + } + + static private Point2D rnd(Random rnd, Point2D pt, double v) { + final double x = pt.getX() + v * rnd.nextDouble(); + final double y = pt.getY() + v * rnd.nextDouble(); + return new Point2D.Double(x, y); } private UPath getSpecificFrontierForCloud(double width, double height) { + if (NEW) { + return getSpecificFrontierForCloudNew(width, height); + } final UPath path = new UPath(); path.moveTo(0, 10); double x = 0; @@ -86,6 +209,8 @@ class USymbolCloud extends USymbol { } private Margin getMargin() { + if (NEW) + return new Margin(15, 15, 15, 15); return new Margin(10, 10, 10, 10); } diff --git a/src/net/sourceforge/plantuml/help/CommandHelp.java b/src/net/sourceforge/plantuml/help/CommandHelp.java index 85288d864..8642bdaba 100644 --- a/src/net/sourceforge/plantuml/help/CommandHelp.java +++ b/src/net/sourceforge/plantuml/help/CommandHelp.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.help; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandHelp extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(Help diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(Help diagram, LineLocation location, RegexResult arg) { diagram.add("General help"); diagram.add(" "); diagram.add("The code of this command is located in net.sourceforge.plantuml.help package."); diff --git a/src/net/sourceforge/plantuml/help/CommandHelpColor.java b/src/net/sourceforge/plantuml/help/CommandHelpColor.java index dcdaaea72..21d200ddb 100644 --- a/src/net/sourceforge/plantuml/help/CommandHelpColor.java +++ b/src/net/sourceforge/plantuml/help/CommandHelpColor.java @@ -35,13 +35,13 @@ */ package net.sourceforge.plantuml.help; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; 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.graphic.HtmlColorSetSimple; -import net.sourceforge.plantuml.syntax.LanguageDescriptor; public class CommandHelpColor extends SingleLineCommand2 { @@ -58,7 +58,7 @@ public class CommandHelpColor extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(Help diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(Help diagram, LineLocation location, RegexResult arg) { diagram.add("Help on colors"); diagram.add(" "); diagram.add("The code of this command is located in net.sourceforge.plantuml.help package."); diff --git a/src/net/sourceforge/plantuml/help/CommandHelpFont.java b/src/net/sourceforge/plantuml/help/CommandHelpFont.java index 7c505c828..4d3c5fa2c 100644 --- a/src/net/sourceforge/plantuml/help/CommandHelpFont.java +++ b/src/net/sourceforge/plantuml/help/CommandHelpFont.java @@ -37,12 +37,12 @@ package net.sourceforge.plantuml.help; import java.awt.GraphicsEnvironment; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; 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.syntax.LanguageDescriptor; public class CommandHelpFont extends SingleLineCommand2 { @@ -59,7 +59,7 @@ public class CommandHelpFont extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(Help diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(Help diagram, LineLocation location, RegexResult arg) { diagram.add("Help on font"); diagram.add(" "); diagram.add("The code of this command is located in net.sourceforge.plantuml.help package."); diff --git a/src/net/sourceforge/plantuml/help/CommandHelpKeyword.java b/src/net/sourceforge/plantuml/help/CommandHelpKeyword.java index bb57068de..2a77c6c5a 100644 --- a/src/net/sourceforge/plantuml/help/CommandHelpKeyword.java +++ b/src/net/sourceforge/plantuml/help/CommandHelpKeyword.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.help; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -57,7 +58,7 @@ public class CommandHelpKeyword extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(Help diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(Help diagram, LineLocation location, RegexResult arg) { diagram.add("Help on keywords"); diagram.add(" "); diagram.add("The code of this command is located in net.sourceforge.plantuml.help package."); diff --git a/src/net/sourceforge/plantuml/help/CommandHelpSkinparam.java b/src/net/sourceforge/plantuml/help/CommandHelpSkinparam.java index 230e13604..35919252c 100644 --- a/src/net/sourceforge/plantuml/help/CommandHelpSkinparam.java +++ b/src/net/sourceforge/plantuml/help/CommandHelpSkinparam.java @@ -35,13 +35,13 @@ */ package net.sourceforge.plantuml.help; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; 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.syntax.LanguageDescriptor; public class CommandHelpSkinparam extends SingleLineCommand2 { @@ -58,7 +58,7 @@ public class CommandHelpSkinparam extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(Help diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(Help diagram, LineLocation location, RegexResult arg) { diagram.add("Help on skinparam"); diagram.add(" "); diagram.add("The code of this command is located in net.sourceforge.plantuml.help package."); diff --git a/src/net/sourceforge/plantuml/help/CommandHelpType.java b/src/net/sourceforge/plantuml/help/CommandHelpType.java index f7f5ff6d8..1eea8f48b 100644 --- a/src/net/sourceforge/plantuml/help/CommandHelpType.java +++ b/src/net/sourceforge/plantuml/help/CommandHelpType.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.help; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -57,7 +58,7 @@ public class CommandHelpType extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(Help diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(Help diagram, LineLocation location, RegexResult arg) { diagram.add("Help on types"); diagram.add(" "); diagram.add("The code of this command is located in net.sourceforge.plantuml.help package."); diff --git a/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java b/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java index 197adbe30..db4e3d58b 100644 --- a/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java +++ b/src/net/sourceforge/plantuml/html/CucaDiagramHtmlMaker.java @@ -127,7 +127,7 @@ public final class CucaDiagramHtmlMaker { if (stereotype != null) { pw.println("


"); pw.println("

Stereotype

"); - for (String s : stereotype.getLabels(diagram.getSkinParam().useGuillemet())) { + for (String s : stereotype.getLabels(diagram.getSkinParam().guillemet())) { pw.println(s); pw.println("
"); } diff --git a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java index eab7d99d8..c1afdff87 100644 --- a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java +++ b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java @@ -336,7 +336,7 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker { if (tmp != null) { return tmp; } - final List stereos = stereotype.getLabels(diagram.getSkinParam().useGuillemet()); + final List stereos = stereotype.getLabels(diagram.getSkinParam().guillemet()); if (stereos == null) { return TextBlockUtils.empty(0, 0); } diff --git a/src/net/sourceforge/plantuml/jdot/DebugUtils.java b/src/net/sourceforge/plantuml/jdot/DebugUtils.java index 5730d05ea..ee7403fde 100644 --- a/src/net/sourceforge/plantuml/jdot/DebugUtils.java +++ b/src/net/sourceforge/plantuml/jdot/DebugUtils.java @@ -39,12 +39,10 @@ import h.ST_Agedgeinfo_t; import h.ST_Agnode_s; import h.ST_Agnodeinfo_t; import h.ST_bezier; -import h.ST_boxf; import h.ST_pointf; import h.ST_splines; import h.ST_textlabel_t; import smetana.core.Macro; -import smetana.core.__ptr__; import smetana.core.amiga.StarStruct; public class DebugUtils { diff --git a/src/net/sourceforge/plantuml/jdot/JDotPath.java b/src/net/sourceforge/plantuml/jdot/JDotPath.java index db5d8ba5b..fa35e8daf 100644 --- a/src/net/sourceforge/plantuml/jdot/JDotPath.java +++ b/src/net/sourceforge/plantuml/jdot/JDotPath.java @@ -39,8 +39,8 @@ import h.ST_Agedge_s; import h.ST_Agedgeinfo_t; import h.ST_bezier; import h.ST_pointf; -import h.ST_textlabel_t; import h.ST_splines; +import h.ST_textlabel_t; import java.awt.geom.Point2D; @@ -62,7 +62,6 @@ import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UTranslate; import smetana.core.Macro; -import smetana.core.__ptr__; public class JDotPath implements UDrawable { diff --git a/src/net/sourceforge/plantuml/jungle/CommandAddLevel.java b/src/net/sourceforge/plantuml/jungle/CommandAddLevel.java index 88a84d715..659f8bf70 100644 --- a/src/net/sourceforge/plantuml/jungle/CommandAddLevel.java +++ b/src/net/sourceforge/plantuml/jungle/CommandAddLevel.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.jungle; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandAddLevel extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(PSystemTree diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(PSystemTree diagram, LineLocation location, RegexResult arg) { final String level = arg.get("LEVEL", 0); final String label = arg.get("LABEL", 0); return diagram.addParagraph(level.length(), label); diff --git a/src/net/sourceforge/plantuml/jungle/CommandEmpty.java b/src/net/sourceforge/plantuml/jungle/CommandEmpty.java index bc95d3566..58f9a979c 100644 --- a/src/net/sourceforge/plantuml/jungle/CommandEmpty.java +++ b/src/net/sourceforge/plantuml/jungle/CommandEmpty.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.jungle; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandEmpty extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(PSystemTree diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(PSystemTree diagram, LineLocation location, RegexResult arg) { return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java b/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java index 760092091..5c803017a 100644 --- a/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java +++ b/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java @@ -51,6 +51,7 @@ import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.graphic.GraphicStrings; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; @@ -150,7 +151,15 @@ public class ScientificEquationSafe { os.write(getSvg(1, foregroundColor, backgroundColor).getSvg(true).getBytes()); return dimSvg; } - return null; + if (fileFormat.getFileFormat() == FileFormat.EPS) { + final BufferedImage image = getImage(scale, foregroundColor, backgroundColor); + final EpsGraphics out = new EpsGraphics(); + out.drawImage(image, 0, 0); + out.close(); + os.write(out.getEPSCode().getBytes()); + return new ImageDataSimple(image.getWidth(), image.getHeight()); + } + throw new UnsupportedOperationException(); } public final String getFormula() { diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.java new file mode 100644 index 000000000..06d09bb03 --- /dev/null +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.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.mindmap; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandMindMapDirection extends SingleLineCommand2 { + + public CommandMindMapDirection() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("[^*]*"), // + new RegexLeaf("DIRECTION", "\\b(left|right)\\b"), // + new RegexLeaf("[^*]*"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { + final String direction = arg.get("DIRECTION", 0); + diagram.setDefaultDirection(Direction.valueOf(direction.toUpperCase())); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeft.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeft.java index 9fe506998..a8ffaefa2 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeft.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeft.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.mindmap; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandMindMapLeft extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(MindMapDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { final String type = arg.get("TYPE", 0); final String label = arg.get("LABEL", 0); return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0)), Direction.LEFT); diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeftNumber.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeftNumber.java index 29e3dabdb..3e1431e0e 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeftNumber.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapLeftNumber.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.mindmap; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandMindMapLeftNumber extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(MindMapDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { final String label = arg.get("LABEL", 0); return diagram.addIdea(Integer.parseInt(arg.get("TYPE", 0)), label, IdeaShape.fromDesc(arg.get("SHAPE", 0)), Direction.LEFT); diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java index b2e9d6fcb..dbed9203a 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java @@ -35,7 +35,7 @@ */ package net.sourceforge.plantuml.mindmap; -import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,10 +58,10 @@ public class CommandMindMapOrgmode extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(MindMapDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { final String type = arg.get("TYPE", 0); final String label = arg.get("LABEL", 0); - return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0)), Direction.RIGHT); + return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0))); } } diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapPlus.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapPlus.java new file mode 100644 index 000000000..09005c140 --- /dev/null +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapPlus.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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.mindmap; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandMindMapPlus extends SingleLineCommand2 { + + public CommandMindMapPlus() { + super(false, getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("TYPE", "([+-]+)"), // + new RegexLeaf("SHAPE", "(_)?"), // + new RegexLeaf("[%s]+"), // + new RegexLeaf("LABEL", "([^%s].*)"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { + final String type = arg.get("TYPE", 0); + final String label = arg.get("LABEL", 0); + final Direction direction = type.contains("-") ? Direction.LEFT : Direction.RIGHT; + return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0)), direction); + } + +} diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapRight.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapRight.java index 492b22789..8a61da5e2 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapRight.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapRight.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.mindmap; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandMindMapRight extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(MindMapDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { final String type = arg.get("TYPE", 0); final String label = arg.get("LABEL", 0); return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0)), Direction.RIGHT); diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapRightNumber.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapRightNumber.java index 299f693aa..e75a1373d 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapRightNumber.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapRightNumber.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.mindmap; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandMindMapRightNumber extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(MindMapDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { final String label = arg.get("LABEL", 0); return diagram.addIdea(0, label, IdeaShape.BOX, null); } diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapTabulation.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapTabulation.java index c9db66f89..8cd4dfe4f 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapTabulation.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapTabulation.java @@ -35,9 +35,7 @@ */ package net.sourceforge.plantuml.mindmap; -import net.sourceforge.plantuml.Direction; -import net.sourceforge.plantuml.command.BlocLines; -import net.sourceforge.plantuml.command.CommandControl; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -60,10 +58,10 @@ public class CommandMindMapTabulation extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(MindMapDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(MindMapDiagram diagram, LineLocation location, RegexResult arg) { final String type = arg.get("TYPE", 0); final String label = arg.get("LABEL", 0); - return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0)), Direction.RIGHT); + return diagram.addIdea(type.length() - 1, label, IdeaShape.fromDesc(arg.get("SHAPE", 0))); } } diff --git a/src/net/sourceforge/plantuml/mindmap/FingerImpl2.java b/src/net/sourceforge/plantuml/mindmap/FingerImpl2.java index d4cef9a9b..295d3e783 100644 --- a/src/net/sourceforge/plantuml/mindmap/FingerImpl2.java +++ b/src/net/sourceforge/plantuml/mindmap/FingerImpl2.java @@ -78,6 +78,7 @@ public class FingerImpl2 implements Finger, UDrawable { for (Idea child : idea.getChildren()) { result.addInNail(build(child, skinParam, direction)); } + // System.err.println("End of build for " + idea); return result; } @@ -135,7 +136,7 @@ public class FingerImpl2 implements Finger, UDrawable { private Tetris tetris(StringBounder stringBounder) { if (tetris == null) { - tetris = new Tetris(); + tetris = new Tetris(label.toString()); for (FingerImpl2 child : nail) { tetris.add(child.asSymetricalTee(stringBounder)); } @@ -201,7 +202,10 @@ public class FingerImpl2 implements Finger, UDrawable { } public double getFullThickness(StringBounder stringBounder) { - return Math.max(getPhalanxThickness(stringBounder), getNailThickness(stringBounder)); + final double thickness1 = getPhalanxThickness(stringBounder); + final double thickness2 = getNailThickness(stringBounder); + // System.err.println("thickness1=" + thickness1 + " thickness2=" + thickness2); + return Math.max(thickness1, thickness2); } public double getFullElongation(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/mindmap/Idea.java b/src/net/sourceforge/plantuml/mindmap/Idea.java index debd04aed..69f9cd9fd 100644 --- a/src/net/sourceforge/plantuml/mindmap/Idea.java +++ b/src/net/sourceforge/plantuml/mindmap/Idea.java @@ -42,7 +42,7 @@ import java.util.List; import net.sourceforge.plantuml.cucadiagram.Display; -public class Idea { +class Idea { private final Display label; private final int level; @@ -50,14 +50,26 @@ public class Idea { private final List children = new ArrayList(); private final IdeaShape shape; - public Idea(int level, Idea parent, Display label, IdeaShape shape) { + public Idea(Display label, IdeaShape shape) { + this(0, null, label, shape); + } + + public Idea createIdea(int newLevel, Display newDisplay, IdeaShape newShape) { + final Idea result = new Idea(newLevel, this, newDisplay, newShape); + this.children.add(result); + return result; + } + + private Idea(int level, Idea parent, Display label, IdeaShape shape) { this.label = label; this.level = level; this.parent = parent; this.shape = shape; - if (parent != null) { - this.parent.children.add(this); - } + } + + @Override + public String toString() { + return label.toString(); } public final int getLevel() { diff --git a/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java b/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java index f7df5e0b3..873fb94fd 100644 --- a/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java +++ b/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java @@ -64,6 +64,15 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class MindMapDiagram extends UmlDiagram { + private Branch left = new Branch(); + private Branch right = new Branch(); + + private Direction defaultDirection = Direction.RIGHT; + + public final void setDefaultDirection(Direction defaultDirection) { + this.defaultDirection = defaultDirection; + } + public DiagramDescription getDescription() { return new DiagramDescription("MindMap"); } @@ -159,8 +168,9 @@ public class MindMapDiagram extends UmlDiagram { } } - private Branch left = new Branch(); - private Branch right = new Branch(); + public CommandExecutionResult addIdea(int level, String label, IdeaShape shape) { + return addIdea(level, label, shape, defaultDirection); + } public CommandExecutionResult addIdea(int level, String label, IdeaShape shape, Direction direction) { if (level == 0) { @@ -184,7 +194,7 @@ public class MindMapDiagram extends UmlDiagram { private Finger finger; private void initRoot(String label, IdeaShape shape) { - root = new Idea(0, null, Display.getWithNewlines(label), shape); + root = new Idea(Display.getWithNewlines(label), shape); last = root; } @@ -198,13 +208,13 @@ public class MindMapDiagram extends UmlDiagram { private CommandExecutionResult add(int level, String label, IdeaShape shape) { if (level == last.getLevel() + 1) { - final Idea newIdea = new Idea(level, last, Display.getWithNewlines(label), shape); + final Idea newIdea = last.createIdea(level, Display.getWithNewlines(label), shape); last = newIdea; return CommandExecutionResult.ok(); } if (level <= last.getLevel()) { final int diff = last.getLevel() - level + 1; - final Idea newIdea = new Idea(level, getParentOfLast(diff), Display.getWithNewlines(label), shape); + final Idea newIdea = getParentOfLast(diff).createIdea(level, Display.getWithNewlines(label), shape); last = newIdea; return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/mindmap/MindMapDiagramFactory.java b/src/net/sourceforge/plantuml/mindmap/MindMapDiagramFactory.java index 1f7194e09..38ee3c640 100644 --- a/src/net/sourceforge/plantuml/mindmap/MindMapDiagramFactory.java +++ b/src/net/sourceforge/plantuml/mindmap/MindMapDiagramFactory.java @@ -56,10 +56,12 @@ public class MindMapDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandMindMapTabulation()); cmds.add(new CommandMindMapOrgmode()); cmds.add(new CommandMindMapRoot()); - cmds.add(new CommandMindMapRight()); - cmds.add(new CommandMindMapRightNumber()); - cmds.add(new CommandMindMapLeft()); - cmds.add(new CommandMindMapLeftNumber()); + cmds.add(new CommandMindMapPlus()); + cmds.add(new CommandMindMapDirection()); +// cmds.add(new CommandMindMapRight()); +// cmds.add(new CommandMindMapRightNumber()); +// cmds.add(new CommandMindMapLeft()); +// cmds.add(new CommandMindMapLeftNumber()); return cmds; } diff --git a/src/net/sourceforge/plantuml/mindmap/SymetricalTee.java b/src/net/sourceforge/plantuml/mindmap/SymetricalTee.java index 9a5d287d7..f8146256e 100644 --- a/src/net/sourceforge/plantuml/mindmap/SymetricalTee.java +++ b/src/net/sourceforge/plantuml/mindmap/SymetricalTee.java @@ -42,6 +42,11 @@ public class SymetricalTee { private final double thickness2; private final double elongation2; + @Override + public String toString() { + return "t1=" + thickness1 + " e1=" + elongation1 + " t2=" + thickness2 + " e2=" + elongation2; + } + public SymetricalTee(double thickness1, double elongation1, double thickness2, double elongation2) { this.thickness1 = thickness1; this.elongation1 = elongation1; diff --git a/src/net/sourceforge/plantuml/mindmap/SymetricalTeePositioned.java b/src/net/sourceforge/plantuml/mindmap/SymetricalTeePositioned.java index 4ae54f104..eac58ea5b 100644 --- a/src/net/sourceforge/plantuml/mindmap/SymetricalTeePositioned.java +++ b/src/net/sourceforge/plantuml/mindmap/SymetricalTeePositioned.java @@ -42,6 +42,11 @@ public class SymetricalTeePositioned { private final SymetricalTee tee; private double y; + @Override + public String toString() { + return "y=" + y + " " + tee; + } + public SymetricalTeePositioned(SymetricalTee tee) { this(tee, 0); } diff --git a/src/net/sourceforge/plantuml/mindmap/Tetris.java b/src/net/sourceforge/plantuml/mindmap/Tetris.java index c0fc3e27b..7510d51fc 100644 --- a/src/net/sourceforge/plantuml/mindmap/Tetris.java +++ b/src/net/sourceforge/plantuml/mindmap/Tetris.java @@ -46,6 +46,16 @@ public class Tetris { private final List elements = new ArrayList(); private double minY = Double.MAX_VALUE; private double maxY = -Double.MAX_VALUE; + private String name; + + public Tetris(String name) { + this.name = name; + } + + @Override + public String toString() { + return name + "(" + elements.size() + ")"; + } public void balance() { if (elements.size() == 0) { @@ -62,6 +72,7 @@ public class Tetris { for (SymetricalTeePositioned stp : elements) { stp.move(-mean); } + // System.err.println("Balanced=" + this + " " + elements); } public double getHeight() { @@ -80,6 +91,7 @@ public class Tetris { } public void add(SymetricalTee tee) { + // System.err.println("Adding in " + this + " " + tee); if (frontier.isEmpty()) { final SymetricalTeePositioned p1 = new SymetricalTeePositioned(tee); @@ -87,8 +99,10 @@ public class Tetris { return; } + // System.err.println("frontier=" + frontier); + final double c1 = frontier.getContact(0, tee.getElongation1()); - final double c2 = frontier.getContact(tee.getElongation1(), tee.getElongation2()); + final double c2 = frontier.getContact(tee.getElongation1(), tee.getElongation1() + tee.getElongation2()); // System.err.println("c1=" + c1 + " c2=" + c2); diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandComment.java b/src/net/sourceforge/plantuml/nwdiag/CommandComment.java index 3c99beaf9..17aff028d 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandComment.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandComment.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandComment extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandElement.java b/src/net/sourceforge/plantuml/nwdiag/CommandElement.java index c95234098..d19955a41 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandElement.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandElement.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandElement extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return diagram.addElement(arg.get("NAME", 0), arg.get("DEFINITION", 1)); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandEndSomething.java b/src/net/sourceforge/plantuml/nwdiag/CommandEndSomething.java index e42364429..db797ab98 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandEndSomething.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandEndSomething.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandEndSomething extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return diagram.endSomething(); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandGroup.java b/src/net/sourceforge/plantuml/nwdiag/CommandGroup.java index bb1b03e95..d6f737ddb 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandGroup.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandGroup.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -60,7 +61,7 @@ public class CommandGroup extends SingleLineCommand2 { @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return diagram.openGroup(arg.get("NAME", 0)); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandLink.java b/src/net/sourceforge/plantuml/nwdiag/CommandLink.java index 6856a6ffa..03dc9f8d6 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandLink.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandLink.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -60,7 +61,7 @@ public class CommandLink extends SingleLineCommand2 { @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return diagram.link(); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandNetwork.java b/src/net/sourceforge/plantuml/nwdiag/CommandNetwork.java index b3ca52173..2aae8b3fa 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandNetwork.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandNetwork.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -59,7 +60,7 @@ public class CommandNetwork extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return diagram.openNetwork(arg.get("NAME", 0)); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandNwDiagInit.java b/src/net/sourceforge/plantuml/nwdiag/CommandNwDiagInit.java index d27de1459..cd6480f81 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandNwDiagInit.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandNwDiagInit.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandNwDiagInit extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { diagram.init(); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/nwdiag/CommandProperty.java b/src/net/sourceforge/plantuml/nwdiag/CommandProperty.java index 12a4f763b..038fa9627 100644 --- a/src/net/sourceforge/plantuml/nwdiag/CommandProperty.java +++ b/src/net/sourceforge/plantuml/nwdiag/CommandProperty.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.nwdiag; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -61,7 +62,7 @@ public class CommandProperty extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(NwDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(NwDiagram diagram, LineLocation location, RegexResult arg) { return diagram.setProperty(arg.get("NAME", 0), arg.get("VALUE", 0)); } diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java index 81fbf167a..4d1287fe2 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.objectdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -73,7 +74,7 @@ public class CommandCreateEntityObject extends SingleLineCommand2 0; - if (VisibilityModifier.isVisibilityCharacter(s)) { + for (StringLocated s : lines) { + assert s.getString().length() > 0; + if (VisibilityModifier.isVisibilityCharacter(s.getString())) { diagram.setVisibilityModifierPresent(true); } - entity.getBodier().addFieldOrMethod(s.toString(), entity); + entity.getBodier().addFieldOrMethod(s.getString(), entity); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java b/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java index 2e8420d8c..72380a539 100644 --- a/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java +++ b/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java @@ -38,7 +38,6 @@ package net.sourceforge.plantuml.posimo; import java.awt.geom.CubicCurve2D; import java.awt.geom.Point2D; import java.util.Collection; -import java.util.Map; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ISkinParam; diff --git a/src/net/sourceforge/plantuml/postit/CommandCreatePostIt.java b/src/net/sourceforge/plantuml/postit/CommandCreatePostIt.java index 4db0cf76d..446d04a58 100644 --- a/src/net/sourceforge/plantuml/postit/CommandCreatePostIt.java +++ b/src/net/sourceforge/plantuml/postit/CommandCreatePostIt.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.postit; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -57,7 +58,7 @@ public class CommandCreatePostIt extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(PostItDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(PostItDiagram diagram, LineLocation location, RegexResult arg) { final String id = arg.get("ID", 0); final String text = arg.get("TEXT", 0); diagram.createPostIt(id, Display.getWithNewlines(text)); diff --git a/src/net/sourceforge/plantuml/postit/PostItDiagram.java b/src/net/sourceforge/plantuml/postit/PostItDiagram.java index 74539d1de..7c047fd64 100644 --- a/src/net/sourceforge/plantuml/postit/PostItDiagram.java +++ b/src/net/sourceforge/plantuml/postit/PostItDiagram.java @@ -77,7 +77,7 @@ public class PostItDiagram extends UmlDiagram { drawU(ug); if (ug instanceof UGraphicG2d) { final BufferedImage im = ((UGraphicG2d) ug).getBufferedImage(); - PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, this.getDpi(fileFormatOption)); + PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96); } else if (ug instanceof UGraphicSvg) { final UGraphicSvg svg = (UGraphicSvg) ug; svg.createXml(os, fileFormatOption.isWithMetadata() ? getMetadata() : null); @@ -123,7 +123,7 @@ public class PostItDiagram extends UmlDiagram { final EmptyImageBuilder builder = new EmptyImageBuilder(width, height, backColor); final Graphics2D graphics2D = builder.getGraphics2D(); - final double dpiFactor = this.getDpiFactor(fileFormatOption); + final double dpiFactor = this.getScaleCoef(fileFormatOption); final UGraphicG2d result = new UGraphicG2d(new ColorMapperIdentity(), graphics2D, dpiFactor); result.setBufferedImage(builder.getBufferedImage()); return result; diff --git a/src/net/sourceforge/plantuml/preproc/IfManager.java b/src/net/sourceforge/plantuml/preproc/IfManager.java index ef806d210..d5a396f60 100644 --- a/src/net/sourceforge/plantuml/preproc/IfManager.java +++ b/src/net/sourceforge/plantuml/preproc/IfManager.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.preproc; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; @@ -62,9 +62,9 @@ public class IfManager extends ReadLineInstrumented implements ReadLine { } @Override - final CharSequence2 readLineInst() throws IOException { + final StringLocated readLineInst() throws IOException { if (child != null) { - final CharSequence2 s = child.readLine(); + final StringLocated s = child.readLine(); if (s != null) { return s; } @@ -74,13 +74,13 @@ public class IfManager extends ReadLineInstrumented implements ReadLine { return readLineInternal(); } - protected CharSequence2 readLineInternal() throws IOException { - final CharSequence2 s = source.readLine(); + protected StringLocated readLineInternal() throws IOException { + final StringLocated s = source.readLine(); if (s == null) { return null; } - Matcher2 m = ifcomparePattern.matcher(s); + Matcher2 m = ifcomparePattern.matcher(s.getString()); if (m.find()) { final int value1 = getValue(m.group(1)); final String operator = m.group(2); @@ -94,7 +94,7 @@ public class IfManager extends ReadLineInstrumented implements ReadLine { return this.readLine(); } - m = ifdefPattern.matcher(s); + m = ifdefPattern.matcher(s.getString()); if (m.find()) { boolean ok = defines.get().isDefine(m.group(2)); if (m.group(1) != null) { diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerFilter.java b/src/net/sourceforge/plantuml/preproc/IfManagerFilter.java index 34ba219a7..3e4f4a690 100644 --- a/src/net/sourceforge/plantuml/preproc/IfManagerFilter.java +++ b/src/net/sourceforge/plantuml/preproc/IfManagerFilter.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.preproc; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc2.ReadFilter; public class IfManagerFilter implements ReadFilter { @@ -57,7 +57,7 @@ public class IfManagerFilter implements ReadFilter { source.close(); } - public CharSequence2 readLine() throws IOException { + public StringLocated readLine() throws IOException { return ifManager.readLine(); } }; diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java b/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java index 681edab47..730df803f 100644 --- a/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java +++ b/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.preproc; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.regex.Matcher2; class IfManagerNegatif extends IfManager { @@ -49,30 +49,30 @@ class IfManagerNegatif extends IfManager { } @Override - protected CharSequence2 readLineInternal() throws IOException { + protected StringLocated readLineInternal() throws IOException { if (skippingDone == false) { skippingDone = true; do { - final CharSequence2 s = readLine(); + final StringLocated s = readLine(); if (s == null) { return null; } - Matcher2 m = endifPattern.matcher(s); + Matcher2 m = endifPattern.matcher(s.getString()); if (m.find()) { return null; } - m = elsePattern.matcher(s); + m = elsePattern.matcher(s.getString()); if (m.find()) { break; } } while (true); } - final CharSequence2 s = super.readLineInternal(); + final StringLocated s = super.readLineInternal(); if (s == null) { return null; } - final Matcher2 m = endifPattern.matcher(s); + final Matcher2 m = endifPattern.matcher(s.getString()); if (m.find()) { return null; } diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java b/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java index 691b573d2..eef7e6a41 100644 --- a/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java +++ b/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.preproc; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.regex.Matcher2; class IfManagerPositif extends IfManager { @@ -47,23 +47,23 @@ class IfManagerPositif extends IfManager { } @Override - protected CharSequence2 readLineInternal() throws IOException { - CharSequence2 s = super.readLineInternal(); + protected StringLocated readLineInternal() throws IOException { + StringLocated s = super.readLineInternal(); if (s == null) { return null; } - Matcher2 m = endifPattern.matcher(s); + Matcher2 m = endifPattern.matcher(s.getString()); if (m.find()) { return null; } - m = elsePattern.matcher(s); + m = elsePattern.matcher(s.getString()); if (m.find()) { do { s = readLine(); if (s == null) { return null; } - m = endifPattern.matcher(s); + m = endifPattern.matcher(s.getString()); if (m.find()) { return null; } diff --git a/src/net/sourceforge/plantuml/preproc/PreprocessorChangeModeReader.java b/src/net/sourceforge/plantuml/preproc/PreprocessorChangeModeReader.java new file mode 100644 index 000000000..e8b86273b --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/PreprocessorChangeModeReader.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.preproc; + +import java.io.IOException; + +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.preproc2.PreprocessorMode; +import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; + +public class PreprocessorChangeModeReader implements ReadLine { + + private final ReadLine raw; + private final PreprocessorModeSet mode; + + public PreprocessorChangeModeReader(ReadLine source, PreprocessorModeSet mode) { + this.raw = source; + this.mode = mode; + } + + public void close() throws IOException { + raw.close(); + } + + public StringLocated readLine() throws IOException { + final StringLocated line = raw.readLine(); + if (line != null && line.getStringTrimmed().endsWith("!preprocessorV2")) { + this.mode.setPreprocessorMode(PreprocessorMode.V2_NEW_TIM); + return new StringLocated("", line.getLocation()); + } + return line; + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/ReadLine.java b/src/net/sourceforge/plantuml/preproc/ReadLine.java index 05c1ee6f5..0dbde88f4 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLine.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLine.java @@ -38,9 +38,9 @@ package net.sourceforge.plantuml.preproc; import java.io.Closeable; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; public interface ReadLine extends Closeable { - public CharSequence2 readLine() throws IOException; + public StringLocated readLine() throws IOException; } diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java b/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java index 57f2edd54..6fe00acf0 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java @@ -35,14 +35,14 @@ */ package net.sourceforge.plantuml.preproc; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; public class ReadLineEmpty implements ReadLine { public void close() { } - public CharSequence2 readLine() { + public StringLocated readLine() { return null; } diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java b/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java index 7cbf96d03..790c66695 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java @@ -40,8 +40,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; -import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringLocated; public abstract class ReadLineInstrumented implements ReadLine { @@ -61,7 +61,7 @@ public abstract class ReadLineInstrumented implements ReadLine { return result; } - public final CharSequence2 readLine() throws IOException { + public final StringLocated readLine() throws IOException { if (TRACE == false) { return readLineInst(); } @@ -80,7 +80,7 @@ public abstract class ReadLineInstrumented implements ReadLine { return super.toString() + " current=" + current; } - abstract CharSequence2 readLineInst() throws IOException; + abstract StringLocated readLineInst() throws IOException; public final void close() throws IOException { if (TRACE) { diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineList.java b/src/net/sourceforge/plantuml/preproc/ReadLineList.java index 62e1cbeb9..8a07a1b3d 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineList.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineList.java @@ -38,16 +38,15 @@ package net.sourceforge.plantuml.preproc; import java.util.Iterator; import java.util.List; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.StringLocated; public class ReadLineList implements ReadLine { - private final Iterator iterator; + private final Iterator iterator; private final LineLocation location; - public ReadLineList(List definition, LineLocation location) { + public ReadLineList(List definition, LineLocation location) { this.iterator = definition.iterator(); this.location = location; } @@ -55,11 +54,11 @@ public class ReadLineList implements ReadLine { public void close() { } - public CharSequence2 readLine() { + public StringLocated readLine() { if (iterator.hasNext() == false) { return null; } - return new CharSequence2Impl(iterator.next(), location); + return new StringLocated(iterator.next(), location); } } diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java index 134170753..547816a97 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java @@ -39,11 +39,10 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocationImpl; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringLocated; public class ReadLineReader extends ReadLineInstrumented implements ReadLine { @@ -80,7 +79,7 @@ public class ReadLineReader extends ReadLineInstrumented implements ReadLine { } @Override - CharSequence2 readLineInst() throws IOException { + StringLocated readLineInst() throws IOException { String s = br.readLine(); location = location.oneLineRead(); if (s == null) { @@ -106,7 +105,7 @@ public class ReadLineReader extends ReadLineInstrumented implements ReadLine { // char c = s.charAt(i); // System.err.println("X " + Integer.toHexString((int) c) + " " + c); // } - return new CharSequence2Impl(s, location); + return new StringLocated(s, location); } @Override diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineSimple.java b/src/net/sourceforge/plantuml/preproc/ReadLineSimple.java index ad90155da..f9544b767 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineSimple.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineSimple.java @@ -35,15 +35,15 @@ */ package net.sourceforge.plantuml.preproc; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; public class ReadLineSimple implements ReadLine { - private final CharSequence2 data; + private final StringLocated data; private final String error; private int current = 0; - public ReadLineSimple(CharSequence2 s2, String error) { + public ReadLineSimple(StringLocated s2, String error) { this.data = s2; this.error = error; } @@ -51,7 +51,7 @@ public class ReadLineSimple implements ReadLine { public void close() { } - public CharSequence2 readLine() { + public StringLocated readLine() { if (current > 0) { return null; } diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineSingle.java b/src/net/sourceforge/plantuml/preproc/ReadLineSingle.java index b25b14c47..2e2e553ba 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineSingle.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineSingle.java @@ -35,21 +35,21 @@ */ package net.sourceforge.plantuml.preproc; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; public class ReadLineSingle implements ReadLine { - private final CharSequence2 data; + private final StringLocated data; private int current = 0; - public ReadLineSingle(CharSequence2 s2) { + public ReadLineSingle(StringLocated s2) { this.data = s2; } public void close() { } - public CharSequence2 readLine() { + public StringLocated readLine() { if (current > 0) { return null; } diff --git a/src/net/sourceforge/plantuml/preproc/StartDiagramExtractReader.java b/src/net/sourceforge/plantuml/preproc/StartDiagramExtractReader.java index b1c255d24..f9a25b205 100644 --- a/src/net/sourceforge/plantuml/preproc/StartDiagramExtractReader.java +++ b/src/net/sourceforge/plantuml/preproc/StartDiagramExtractReader.java @@ -41,8 +41,8 @@ import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; -import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.utils.StartUtils; public class StartDiagramExtractReader implements ReadLine { @@ -50,15 +50,15 @@ public class StartDiagramExtractReader implements ReadLine { private final ReadLine raw; private boolean finished = false; - public static StartDiagramExtractReader build(FileWithSuffix f2, CharSequence2 s, String charset) { + public static StartDiagramExtractReader build(FileWithSuffix f2, StringLocated s, String charset) { return new StartDiagramExtractReader(getReadLine(f2, s, charset), f2.getSuffix()); } - public static StartDiagramExtractReader build(URL url, CharSequence2 s, String uid, String charset) { + public static StartDiagramExtractReader build(URL url, StringLocated s, String uid, String charset) { return new StartDiagramExtractReader(getReadLine(url, s, charset), uid); } - public static StartDiagramExtractReader build(InputStream is, CharSequence2 s, String desc) { + public static StartDiagramExtractReader build(InputStream is, StringLocated s, String desc) { return new StartDiagramExtractReader(getReadLine(is, s, desc), null); } @@ -74,10 +74,10 @@ public class StartDiagramExtractReader implements ReadLine { bloc = 0; } this.raw = raw; - CharSequence2 s = null; + StringLocated s = null; try { while ((s = raw.readLine()) != null) { - if (StartUtils.isArobaseStartDiagram(s) && checkUid(uid, s)) { + if (StartUtils.isArobaseStartDiagram(s.getString()) && checkUid(uid, s)) { if (bloc == 0) { return; } @@ -91,7 +91,7 @@ public class StartDiagramExtractReader implements ReadLine { finished = true; } - private boolean checkUid(String uid, CharSequence2 s) { + private boolean checkUid(String uid, StringLocated s) { if (uid == null) { return true; } @@ -101,7 +101,7 @@ public class StartDiagramExtractReader implements ReadLine { return false; } - private static ReadLine getReadLine(FileWithSuffix f2, CharSequence2 s, String charset) { + private static ReadLine getReadLine(FileWithSuffix f2, StringLocated s, String charset) { try { final Reader tmp1 = f2.getReader(charset); if (tmp1 == null) { @@ -113,11 +113,11 @@ public class StartDiagramExtractReader implements ReadLine { } } - private static ReadLine getReadLine(InputStream is, CharSequence2 s, String description) { + private static ReadLine getReadLine(InputStream is, StringLocated s, String description) { return new UncommentReadLine(ReadLineReader.create(new InputStreamReader(is), description)); } - private static ReadLine getReadLine(URL url, CharSequence2 s, String charset) { + private static ReadLine getReadLine(URL url, StringLocated s, String charset) { try { if (charset == null) { Log.info("Using default charset"); @@ -132,26 +132,26 @@ public class StartDiagramExtractReader implements ReadLine { } } - static public boolean containsStartDiagram(FileWithSuffix f2, CharSequence2 s, String charset) throws IOException { + static public boolean containsStartDiagram(FileWithSuffix f2, StringLocated s, String charset) throws IOException { final ReadLine r = getReadLine(f2, s, charset); return containsStartDiagram(r); } - static public boolean containsStartDiagram(URL url, CharSequence2 s, String charset) throws IOException { + static public boolean containsStartDiagram(URL url, StringLocated s, String charset) throws IOException { final ReadLine r = getReadLine(url, s, charset); return containsStartDiagram(r); } - static public boolean containsStartDiagram(InputStream is, CharSequence2 s, String description) throws IOException { + static public boolean containsStartDiagram(InputStream is, StringLocated s, String description) throws IOException { final ReadLine r = getReadLine(is, s, description); return containsStartDiagram(r); } private static boolean containsStartDiagram(final ReadLine r) throws IOException { try { - CharSequence2 s = null; + StringLocated s = null; while ((s = r.readLine()) != null) { - if (StartUtils.isArobaseStartDiagram(s)) { + if (StartUtils.isArobaseStartDiagram(s.getString())) { return true; } } @@ -163,12 +163,12 @@ public class StartDiagramExtractReader implements ReadLine { return false; } - public CharSequence2 readLine() throws IOException { + public StringLocated readLine() throws IOException { if (finished) { return null; } - final CharSequence2 result = raw.readLine(); - if (result != null && StartUtils.isArobaseEndDiagram(result)) { + final StringLocated result = raw.readLine(); + if (result != null && StartUtils.isArobaseEndDiagram(result.getString())) { finished = true; return null; } diff --git a/src/net/sourceforge/plantuml/preproc/Sub.java b/src/net/sourceforge/plantuml/preproc/Sub.java index e946ae6cf..a29040195 100644 --- a/src/net/sourceforge/plantuml/preproc/Sub.java +++ b/src/net/sourceforge/plantuml/preproc/Sub.java @@ -38,20 +38,20 @@ package net.sourceforge.plantuml.preproc; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.StringLocated; public class Sub { private final String name; - private final List lines = new ArrayList(); + private final List lines = new ArrayList(); public Sub(String name) { this.name = name; } - public void add(CharSequence2 s) { - this.lines.add(s); + public void add(StringLocated s) { + this.lines.add(s.getString()); } public ReadLine getReadLine(LineLocation lineLocation) { diff --git a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java index 66a8e0484..6403e3968 100644 --- a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java +++ b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java @@ -37,8 +37,7 @@ package net.sourceforge.plantuml.preproc; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; @@ -64,8 +63,8 @@ public class UncommentReadLine extends ReadLineInstrumented implements ReadLine } @Override - CharSequence2 readLineInst() throws IOException { - final CharSequence2 result = raw.readLine(); + StringLocated readLineInst() throws IOException { + final StringLocated result = raw.readLine(); if (result == null) { return null; @@ -75,21 +74,21 @@ public class UncommentReadLine extends ReadLineInstrumented implements ReadLine // if (m.find()) { // headerToRemove = m.group(1); // } - final String tmp = StartUtils.beforeStartUml(result); + final String tmp = StartUtils.beforeStartUml(result.getString()); if (tmp != null) { headerToRemove = tmp; } if (paused) { - final Matcher2 m2 = unpause.matcher(result); + final Matcher2 m2 = unpause.matcher(result.getString()); if (m2.find()) { headerToRemove = m2.group(1); } } - if (headerToRemove != null && headerToRemove.startsWith(result.toString2())) { - return new CharSequence2Impl("", result.getLocation()); + if (headerToRemove != null && headerToRemove.startsWith(result.getString())) { + return new StringLocated("", result.getLocation()); } - if (headerToRemove != null && result.toString2().startsWith(headerToRemove)) { - return result.subSequence(headerToRemove.length(), result.length()); + if (headerToRemove != null && result.getString().startsWith(headerToRemove)) { + return result.sub(headerToRemove.length(), result.getString().length()); } return result; } diff --git a/src/net/sourceforge/plantuml/preproc2/Preprocessor2.java b/src/net/sourceforge/plantuml/preproc2/Preprocessor.java similarity index 69% rename from src/net/sourceforge/plantuml/preproc2/Preprocessor2.java rename to src/net/sourceforge/plantuml/preproc2/Preprocessor.java index ddd28454a..f8b125e7d 100644 --- a/src/net/sourceforge/plantuml/preproc2/Preprocessor2.java +++ b/src/net/sourceforge/plantuml/preproc2/Preprocessor.java @@ -41,8 +41,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.DefinitionsContainer; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.FileWithSuffix; @@ -51,39 +51,52 @@ import net.sourceforge.plantuml.preproc.ImportedFiles; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineNumbered; -public class Preprocessor2 implements ReadLineNumbered { +public class Preprocessor implements ReadLineNumbered { private final ReadLine source; - private final PreprocessorInclude3 include; + private final PreprocessorInclude include; + private final PreprocessorModeSet mode; + private final ReadLine sourceV2; - public Preprocessor2(List config, ReadLine reader, String charset, Defines defines, + public Preprocessor(List config, ReadLine reader, String charset, Defines defines, DefinitionsContainer definitionsContainer, ImportedFiles importedFiles) throws IOException { this(config, reader, charset, new DefinesGet(defines), definitionsContainer, new HashSet(), importedFiles, true); } - Preprocessor2(List config, ReadLine reader, String charset, DefinesGet defines, + Preprocessor(List config, ReadLine reader, String charset, DefinesGet defines, DefinitionsContainer definitionsContainer, Set filesUsedGlobal, ImportedFiles importedFiles, boolean doSaveState) throws IOException { - final ReadFilterAnd2 filters = new ReadFilterAnd2(); + this.mode = definitionsContainer; if (doSaveState) { defines.saveState(); } + final ReadFilterAnd filtersV2 = new ReadFilterAnd(); + filtersV2.add(new ReadLineQuoteComment()); + this.sourceV2 = filtersV2.applyFilter(reader); - filters.add(new ReadLineQuoteComment2()); - include = new PreprocessorInclude3(config, charset, defines, definitionsContainer, importedFiles, + final ReadFilterAnd filters = new ReadFilterAnd(); + filters.add(new ReadLineQuoteComment()); + include = new PreprocessorInclude(config, charset, defines, definitionsContainer, importedFiles, filesUsedGlobal); - filters.add(new ReadLineAddConfig2(config)); + filters.add(new ReadLineAddConfig(config)); filters.add(new IfManagerFilter(defines)); - filters.add(new PreprocessorDefine4Apply(defines)); - filters.add(new SubPreprocessor2(charset, definitionsContainer)); - filters.add(new PreprocessorDefine3Learner(defines, importedFiles.getCurrentDir())); + filters.add(new PreprocessorDefineApply(defines)); + filters.add(new SubPreprocessor(charset, definitionsContainer)); + filters.add(new PreprocessorDefineLearner(defines, importedFiles.getCurrentDir())); filters.add(include); this.source = filters.applyFilter(reader); } - public CharSequence2 readLine() throws IOException { + private boolean isV2() { + return mode != null && mode.getPreprocessorMode() == PreprocessorMode.V2_NEW_TIM; + } + + public StringLocated readLine() throws IOException { + if (isV2()) { + return sourceV2.readLine(); + } return source.readLine(); } diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefine4Apply.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineApply.java similarity index 79% rename from src/net/sourceforge/plantuml/preproc2/PreprocessorDefine4Apply.java rename to src/net/sourceforge/plantuml/preproc2/PreprocessorDefineApply.java index fc519281d..825bbc93d 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefine4Apply.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineApply.java @@ -38,17 +38,16 @@ package net.sourceforge.plantuml.preproc2; import java.io.IOException; import java.util.List; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineList; -public class PreprocessorDefine4Apply implements ReadFilter { +public class PreprocessorDefineApply implements ReadFilter { private final DefinesGet defines; - public PreprocessorDefine4Apply(DefinesGet defines) throws IOException { + public PreprocessorDefineApply(DefinesGet defines) throws IOException { this.defines = defines; } @@ -70,21 +69,21 @@ public class PreprocessorDefine4Apply implements ReadFilter { } @Override - CharSequence2 readLineInternal() throws IOException { - final CharSequence2 s = this.source.readLine(); + StringLocated readLineInternal() throws IOException { + final StringLocated s = this.source.readLine(); if (s == null || s.getPreprocessorError() != null) { return s; } - if (PreprocessorDefine3Learner.isLearningLine(s)) { + if (PreprocessorDefineLearner.isLearningLine(s)) { return s; } - final List result = defines.get().applyDefines(s.toString2()); + final List result = defines.get().applyDefines(s.getString()); if (result.size() > 1) { insert(new ReadLineList(result, s.getLocation())); return readLine(); } String tmp = result.get(0); - return new CharSequence2Impl(tmp, s.getLocation(), s.getPreprocessorError()); + return new StringLocated(tmp, s.getLocation(), s.getPreprocessorError()); } } diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefine3Learner.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineLearner.java similarity index 81% rename from src/net/sourceforge/plantuml/preproc2/PreprocessorDefine3Learner.java rename to src/net/sourceforge/plantuml/preproc2/PreprocessorDefineLearner.java index 871871ff8..fa9dbec4b 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefine3Learner.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineLearner.java @@ -40,7 +40,7 @@ import java.util.ArrayList; import java.util.List; import net.sourceforge.plantuml.AParentFolder; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.utils.StartUtils; -public class PreprocessorDefine3Learner implements ReadFilter { +public class PreprocessorDefineLearner implements ReadFilter { private static final String END_DEFINE_LONG = "!enddefinelong"; private static final String ID = "[A-Za-z_][A-Za-z_0-9]*"; @@ -65,21 +65,21 @@ public class PreprocessorDefine3Learner implements ReadFilter { private final DefinesGet defines; private final AParentFolder currentDir; - public PreprocessorDefine3Learner(DefinesGet defines, AParentFolder currentDir) { + public PreprocessorDefineLearner(DefinesGet defines, AParentFolder currentDir) { this.defines = defines; this.currentDir = currentDir; } - public static boolean isLearningLine(CharSequence2 s) { - Matcher2 m = defineShortPattern.matcher(s); + public static boolean isLearningLine(StringLocated s) { + Matcher2 m = defineShortPattern.matcher(s.getString()); if (m.find()) { return true; } - m = definelongPattern.matcher(s); + m = definelongPattern.matcher(s.getString()); if (m.find()) { return true; } - m = undefPattern.matcher(s); + m = undefPattern.matcher(s.getString()); if (m.find()) { return true; } @@ -93,34 +93,34 @@ public class PreprocessorDefine3Learner implements ReadFilter { source.close(); } - public CharSequence2 readLine() throws IOException { + public StringLocated readLine() throws IOException { while (true) { - final CharSequence2 s = source.readLine(); + final StringLocated s = source.readLine(); if (s == null || s.getPreprocessorError() != null) { return s; } - if (StartUtils.isArobaseStartDiagram(s)) { + if (StartUtils.isArobaseStartDiagram(s.getString())) { defines.restoreState(); return s; } - Matcher2 m = filenamePattern.matcher(s); + Matcher2 m = filenamePattern.matcher(s.getString()); if (m.find()) { manageFilename(m); continue; } - m = defineShortPattern.matcher(s); + m = defineShortPattern.matcher(s.getString()); if (m.find()) { - manageDefineShort(source, m, s.toString().trim().endsWith("()")); + manageDefineShort(source, m, s.getString().trim().endsWith("()")); continue; } - m = definelongPattern.matcher(s); + m = definelongPattern.matcher(s.getString()); if (m.find()) { - manageDefineLong(source, m, s.toString().trim().endsWith("()")); + manageDefineLong(source, m, s.getString().trim().endsWith("()")); continue; } - m = undefPattern.matcher(s); + m = undefPattern.matcher(s.getString()); if (m.find()) { manageUndef(m); continue; @@ -139,15 +139,15 @@ public class PreprocessorDefine3Learner implements ReadFilter { final String group1 = m.group(1); final List def = new ArrayList(); while (true) { - final CharSequence2 read = source.readLine(); + final StringLocated read = source.readLine(); if (read == null) { return; } - if (enddefinelongPattern.matcher(read).find()) { + if (enddefinelongPattern.matcher(read.getString()).find()) { defines.get().define(group1, def, emptyParentheses, currentDir); return; } - def.add(read.toString2()); + def.add(read.getString()); } } @@ -169,8 +169,8 @@ public class PreprocessorDefine3Learner implements ReadFilter { final StringBuilder value = new StringBuilder(strings.get(0)); while (StringUtils.endsWithBackslash(value.toString())) { value.setLength(value.length() - 1); - final CharSequence2 read = source.readLine(); - value.append(read.toString2()); + final StringLocated read = source.readLine(); + value.append(read.getString()); } final List li = new ArrayList(); li.add(value.toString()); diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude3.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java similarity index 85% rename from src/net/sourceforge/plantuml/preproc2/PreprocessorInclude3.java rename to src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java index f12c5fbd9..bbd39f306 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude3.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java @@ -49,16 +49,15 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.DefinitionsContainer; import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.FileWithSuffix; import net.sourceforge.plantuml.preproc.ImportedFiles; @@ -72,7 +71,7 @@ import net.sourceforge.plantuml.preproc.StartDiagramExtractReader; import net.sourceforge.plantuml.preproc.Stdlib; import net.sourceforge.plantuml.utils.StartUtils; -public class PreprocessorInclude3 implements ReadFilter { +public class PreprocessorInclude implements ReadFilter { private static final Pattern2 includeDefPattern = MyPattern.cmpile("^[%s]*!includedef[%s]+[%g]?([^%g]+)[%g]?$"); @@ -96,7 +95,7 @@ public class PreprocessorInclude3 implements ReadFilter { private final Set filesUsedGlobal; private PreprocessorIncludeStrategy strategy = PreprocessorIncludeStrategy.ONCE; - public PreprocessorInclude3(List config, String charset, DefinesGet defines, + public PreprocessorInclude(List config, String charset, DefinesGet defines, DefinitionsContainer definitionsContainer, ImportedFiles importedFiles, Set filesUsedGlobal) { this.charset = charset; this.config = config; @@ -124,8 +123,8 @@ public class PreprocessorInclude3 implements ReadFilter { } @Override - CharSequence2 readLineInternal() throws IOException { - final CharSequence2 s = source.readLine(); + StringLocated readLineInternal() throws IOException { + final StringLocated s = source.readLine(); if (s == null || s.getPreprocessorError() != null) { return s; } @@ -136,47 +135,47 @@ public class PreprocessorInclude3 implements ReadFilter { return s; } if (s.getPreprocessorError() == null && OptionFlags.ALLOW_INCLUDE) { - final Matcher2 m0 = importPattern.matcher(s); + final Matcher2 m0 = importPattern.matcher(s.getString()); if (m0.find()) { - final CharSequence2 err = manageFileImport(s, m0); + final StringLocated err = manageFileImport(s, m0); if (err != null) { insert(new ReadLineSingle(err)); } return readLine(); } - final Matcher2 m1 = includePattern.matcher(s); + final Matcher2 m1 = includePattern.matcher(s.getString()); if (m1.find()) { insert(manageFileInclude(s, m1, strategy)); return readLine(); } - final Matcher2 m2 = includeManyPattern.matcher(s); + final Matcher2 m2 = includeManyPattern.matcher(s.getString()); if (m2.find()) { insert(manageFileInclude(s, m2, PreprocessorIncludeStrategy.MANY)); return readLine(); } - final Matcher2 m3 = includeOncePattern.matcher(s); + final Matcher2 m3 = includeOncePattern.matcher(s.getString()); if (m3.find()) { insert(manageFileInclude(s, m3, PreprocessorIncludeStrategy.ONCE)); return readLine(); } - final Matcher2 m4 = includeDefPattern.matcher(s); + final Matcher2 m4 = includeDefPattern.matcher(s.getString()); if (m4.find()) { insert(manageDefinitionInclude(s, m4)); return readLine(); } } else { - final Matcher2 m1 = includePatternStdlib.matcher(s); + final Matcher2 m1 = includePatternStdlib.matcher(s.getString()); if (m1.find()) { insert(manageFileInclude(s, m1, PreprocessorIncludeStrategy.ONCE)); return readLine(); } } - final Matcher2 mUrl = includeURLPattern.matcher(s); + final Matcher2 mUrl = includeURLPattern.matcher(s.getString()); if (s.getPreprocessorError() == null && mUrl.find()) { insert(manageUrlInclude(s, mUrl)); return readLine(); } - final Matcher2 m2 = includeDefaultStrategy.matcher(s); + final Matcher2 m2 = includeDefaultStrategy.matcher(s.getString()); if (m2.find()) { strategy = PreprocessorIncludeStrategy.fromString(m2.group(1)); return readLine(); @@ -187,7 +186,7 @@ public class PreprocessorInclude3 implements ReadFilter { } - private CharSequence2 manageFileImport(CharSequence2 s, Matcher2 m) throws IOException { + private StringLocated manageFileImport(StringLocated s, Matcher2 m) throws IOException { final String fileName = m.group(1); final File file = FileSystem.getInstance().getFile(withEnvironmentVariable(fileName)); if (file.exists() && file.isDirectory() == false) { @@ -198,7 +197,7 @@ public class PreprocessorInclude3 implements ReadFilter { } - private ReadLine manageUrlInclude(CharSequence2 s, Matcher2 m) throws IOException { + private ReadLine manageUrlInclude(StringLocated s, Matcher2 m) throws IOException { String urlString = m.group(1); urlString = defines.get().applyDefines(urlString).get(0); @@ -214,7 +213,7 @@ public class PreprocessorInclude3 implements ReadFilter { return new ReadLineSingle(s.withErrorPreprocessor("Cannot include url " + urlString)); } final URL url = new URL(urlString); - return new Preprocessor2(config, getReaderInclude(url, s, suf), charset, defines, definitionsContainer, + return new Preprocessor(config, getReaderIncludeUrl(url, s, suf, charset), charset, defines, definitionsContainer, filesUsedGlobal, importedFiles, false); } catch (MalformedURLException e) { @@ -222,14 +221,14 @@ public class PreprocessorInclude3 implements ReadFilter { } } - private ReadLine manageDefinitionInclude(CharSequence2 s, Matcher2 matcher) throws IOException { + private ReadLine manageDefinitionInclude(StringLocated s, Matcher2 matcher) throws IOException { final String definitionName = matcher.group(1); - final List definition = definitionsContainer.getDefinition(definitionName); - return new Preprocessor2(config, new ReadLineList(definition, s.getLocation()), charset, defines, + final List definition = definitionsContainer.getDefinition(definitionName); + return new Preprocessor(config, new ReadLineList(definition, s.getLocation()), charset, defines, definitionsContainer, filesUsedGlobal, importedFiles, false); } - private ReadLine manageFileInclude(CharSequence2 s, Matcher2 matcher, PreprocessorIncludeStrategy allowMany) + private ReadLine manageFileInclude(StringLocated s, Matcher2 matcher, PreprocessorIncludeStrategy allowMany) throws IOException { String fileName = matcher.group(1); fileName = defines.get().applyDefines(fileName).get(0); @@ -238,7 +237,7 @@ public class PreprocessorInclude3 implements ReadFilter { if (strlibReader == null) { return new ReadLineSingle(s.withErrorPreprocessor("Cannot include " + fileName)); } - return new Preprocessor2(config, strlibReader, charset, defines, definitionsContainer, filesUsedGlobal, + return new Preprocessor(config, strlibReader, charset, defines, definitionsContainer, filesUsedGlobal, importedFiles, false); } final int idx = fileName.lastIndexOf('!'); @@ -259,7 +258,7 @@ public class PreprocessorInclude3 implements ReadFilter { filesUsedCurrent.add(f2); filesUsedGlobal.add(f2); - return new Preprocessor2(config, getReaderInclude(f2, s), charset, defines, definitionsContainer, + return new Preprocessor(config, getReaderInclude(f2, s), charset, defines, definitionsContainer, filesUsedGlobal, importedFiles.withCurrentDir(f2.getParentFile()), false); } @@ -292,13 +291,13 @@ public class PreprocessorInclude3 implements ReadFilter { return null; } - private InputStream getStdlibInputStream(String filename) { + private static InputStream getStdlibInputStream(String filename) { final InputStream result = Stdlib.getResourceAsStream(filename); // Log.info("Loading sdlib " + filename + " ok"); return result; } - private ReadLine getReaderStdlibInclude(CharSequence2 s, String filename) { + public static ReadLine getReaderStdlibInclude(StringLocated s, String filename) { Log.info("Loading sdlib " + filename); InputStream is = getStdlibInputStream(filename); if (is == null) { @@ -321,7 +320,7 @@ public class PreprocessorInclude3 implements ReadFilter { } } - private ReadLine getReaderInclude(FileWithSuffix f2, CharSequence2 s) { + private ReadLine getReaderInclude(FileWithSuffix f2, StringLocated s) { try { if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) { return StartDiagramExtractReader.build(f2, s, charset); @@ -337,7 +336,7 @@ public class PreprocessorInclude3 implements ReadFilter { } } - private ReadLine getReaderInclude(final URL url, CharSequence2 s, String suf) { + public 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); diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorMode.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorMode.java new file mode 100644 index 000000000..8ecf41c05 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorMode.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.preproc2; + +public enum PreprocessorMode { + + V1_LEGACY, V2_NEW_TIM + +} diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineList2.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java similarity index 65% rename from src/net/sourceforge/plantuml/preproc2/ReadLineList2.java rename to src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java index 975ebf3b5..db40f537a 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineList2.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java @@ -35,35 +35,15 @@ */ package net.sourceforge.plantuml.preproc2; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import net.sourceforge.plantuml.preproc.ImportedFiles; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.preproc.FileWithSuffix; -import net.sourceforge.plantuml.preproc.ReadLineNumbered; +public interface PreprocessorModeSet { -public class ReadLineList2 implements ReadLineNumbered { + public PreprocessorMode getPreprocessorMode(); - private final Iterator iterator; + public void setPreprocessorMode(PreprocessorMode mode); + + public ImportedFiles getImportedFiles(); - public ReadLineList2(List definition) { - this.iterator = definition.iterator(); - } - - public void close() { - } - - public CharSequence2 readLine() { - if (iterator.hasNext() == false) { - return null; - } - return iterator.next(); - } - - public Set getFilesUsed() { - return Collections.emptySet(); - } } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadFilterAnd2.java b/src/net/sourceforge/plantuml/preproc2/ReadFilterAnd.java similarity index 81% rename from src/net/sourceforge/plantuml/preproc2/ReadFilterAnd2.java rename to src/net/sourceforge/plantuml/preproc2/ReadFilterAnd.java index dd310c2e8..718c46a39 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadFilterAnd2.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadFilterAnd.java @@ -40,7 +40,7 @@ import java.util.Collection; import net.sourceforge.plantuml.preproc.ReadLine; -public class ReadFilterAnd2 implements ReadFilter { +public class ReadFilterAnd implements ReadFilter { private final Collection all = new ArrayList(); @@ -53,13 +53,6 @@ public class ReadFilterAnd2 implements ReadFilter { current = f.applyFilter(current); } return current; - // if (filter3 == null && filter4 == null) { - // return filter2.applyFilter(filter1.applyFilter(source)); - // } - // if (filter4 == null) { - // return filter3.applyFilter(filter2.applyFilter(filter1.applyFilter(source))); - // } - // return filter4.applyFilter(filter3.applyFilter(filter2.applyFilter(filter1.applyFilter(source)))); } } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig2.java b/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java similarity index 84% rename from src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig2.java rename to src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java index fca5ddab8..0b31444f4 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig2.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java @@ -38,16 +38,16 @@ package net.sourceforge.plantuml.preproc2; import java.io.IOException; import java.util.List; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineList; import net.sourceforge.plantuml.utils.StartUtils; -public class ReadLineAddConfig2 implements ReadFilter { +public class ReadLineAddConfig implements ReadFilter { private final List config; - public ReadLineAddConfig2(List config) { + public ReadLineAddConfig(List config) { this.config = config; } @@ -61,8 +61,8 @@ public class ReadLineAddConfig2 implements ReadFilter { raw.close(); } - public CharSequence2 readLine() throws IOException { - CharSequence2 result = null; + public StringLocated readLine() throws IOException { + StringLocated result = null; if (inserted != null) { result = inserted.readLine(); if (result == null) { @@ -73,8 +73,8 @@ public class ReadLineAddConfig2 implements ReadFilter { } } result = raw.readLine(); - if (result != null && StartUtils.isArobaseStartDiagram(result) && config.size() > 0) { - inserted = new ReadLineQuoteComment2().applyFilter(new ReadLineList(config, result.getLocation())); + if (result != null && StartUtils.isArobaseStartDiagram(result.getString()) && config.size() > 0) { + inserted = new ReadLineQuoteComment().applyFilter(new ReadLineList(config, result.getLocation())); } return result; } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java b/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java index 49a0a3515..3d2513cb0 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java @@ -39,7 +39,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc.ReadLine; public abstract class ReadLineInsertable implements ReadLine { @@ -50,12 +50,12 @@ public abstract class ReadLineInsertable implements ReadLine { sources.add(0, inserted); } - abstract CharSequence2 readLineInternal() throws IOException; + abstract StringLocated readLineInternal() throws IOException; - final public CharSequence2 readLine() throws IOException { + final public StringLocated readLine() throws IOException { while (sources.size() > 0) { final ReadLine tmp = sources.get(0); - final CharSequence2 result = tmp.readLine(); + final StringLocated result = tmp.readLine(); if (result != null) { return result; } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment2.java b/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java similarity index 83% rename from src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment2.java rename to src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java index 5516915ff..6587c9ded 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment2.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java @@ -37,11 +37,10 @@ package net.sourceforge.plantuml.preproc2; import java.io.IOException; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc.ReadLine; -public class ReadLineQuoteComment2 implements ReadFilter { +public class ReadLineQuoteComment implements ReadFilter { public ReadLine applyFilter(final ReadLine source) { return new ReadLine() { @@ -50,14 +49,14 @@ public class ReadLineQuoteComment2 implements ReadFilter { source.close(); } - public CharSequence2 readLine() throws IOException { + public StringLocated readLine() throws IOException { boolean longComment = false; while (true) { - final CharSequence2 result = source.readLine(); + final StringLocated result = source.readLine(); if (result == null) { return null; } - final String trim = result.toString().replace('\t', ' ').trim(); + final String trim = result.getString().replace('\t', ' ').trim(); if (longComment && trim.endsWith("'/")) { longComment = false; continue; @@ -75,7 +74,7 @@ public class ReadLineQuoteComment2 implements ReadFilter { longComment = true; continue; } - return ((CharSequence2Impl) result).removeInnerComment(); + return ((StringLocated) result).removeInnerComment(); } } }; diff --git a/src/net/sourceforge/plantuml/preproc2/SubPreprocessor2.java b/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java similarity index 83% rename from src/net/sourceforge/plantuml/preproc2/SubPreprocessor2.java rename to src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java index 3f7f8a82f..115b8c410 100644 --- a/src/net/sourceforge/plantuml/preproc2/SubPreprocessor2.java +++ b/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java @@ -43,22 +43,20 @@ import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; -import net.sourceforge.plantuml.CharSequence2; import net.sourceforge.plantuml.DefinitionsContainer; import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.preproc.Defines; -import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.FileWithSuffix; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineReader; import net.sourceforge.plantuml.preproc.ReadLineSimple; import net.sourceforge.plantuml.preproc.Sub; -public class SubPreprocessor2 implements ReadFilter { +public class SubPreprocessor implements ReadFilter { private static final String ID = "[A-Za-z_][A-Za-z_0-9]*"; @@ -70,7 +68,7 @@ public class SubPreprocessor2 implements ReadFilter { private final DefinitionsContainer definitionsContainer; private final String charset; - public SubPreprocessor2(String charset, DefinitionsContainer definitionsContainer) { + public SubPreprocessor(String charset, DefinitionsContainer definitionsContainer) { this.charset = charset; this.definitionsContainer = definitionsContainer; } @@ -90,13 +88,13 @@ public class SubPreprocessor2 implements ReadFilter { this.source = source; } - private CharSequence2 manageStartsub(Matcher2 m) throws IOException { + private StringLocated manageStartsub(Matcher2 m) throws IOException { final String name = m.group(1); learningSub = getSub(name); return this.readLine(); } - private CharSequence2 manageEndsub(Matcher2 m) throws IOException { + private StringLocated manageEndsub(Matcher2 m) throws IOException { learningSub = null; return this.readLine(); } @@ -105,18 +103,18 @@ public class SubPreprocessor2 implements ReadFilter { source.close(); } - private CharSequence2 manageIncludeSub(CharSequence2 s, Matcher2 m) throws IOException { + private StringLocated manageIncludeSub(StringLocated s, Matcher2 m) throws IOException { final String name = m.group(1); final int idx = name.indexOf('!'); if (idx != -1) { final String filename = name.substring(0, idx); final String blocname = name.substring(idx + 1); - final File f = FileSystem.getInstance().getFile(PreprocessorInclude3.withEnvironmentVariable(filename)); + final File f = FileSystem.getInstance().getFile(PreprocessorInclude.withEnvironmentVariable(filename)); if (f.exists() == false || f.isDirectory()) { Log.error("Cannot include " + FileWithSuffix.getAbsolutePath(f)); return s.withErrorPreprocessor("Cannot include " + FileWithSuffix.getFileName(f)); } - final SubPreprocessor2 data = new SubPreprocessor2(charset, definitionsContainer); + final SubPreprocessor data = new SubPreprocessor(charset, definitionsContainer); InnerReadLine tmp = (InnerReadLine) data.applyFilter(getReaderInclude(s, f)); while (tmp.readLine() != null) { // Read file @@ -129,9 +127,9 @@ public class SubPreprocessor2 implements ReadFilter { return this.readLine(); } - public CharSequence2 readLine() throws IOException { + public StringLocated readLine() throws IOException { if (includedSub != null) { - final CharSequence2 s = includedSub.readLine(); + final StringLocated s = includedSub.readLine(); if (s != null) { eventuallyLearn(s); return s; @@ -139,22 +137,22 @@ public class SubPreprocessor2 implements ReadFilter { includedSub = null; } - final CharSequence2 s = source.readLine(); + final StringLocated s = source.readLine(); if (s == null) { return null; } - final Matcher2 m1 = includeSubPattern.matcher(s); + final Matcher2 m1 = includeSubPattern.matcher(s.getString()); if (m1.find()) { return manageIncludeSub(s, m1); } - Matcher2 m = startsub.matcher(s); + Matcher2 m = startsub.matcher(s.getString()); if (m.find()) { return manageStartsub(m); } - m = endsub.matcher(s); + m = endsub.matcher(s.getString()); if (m.find()) { return manageEndsub(m); } @@ -162,7 +160,7 @@ public class SubPreprocessor2 implements ReadFilter { return s; } - private void eventuallyLearn(final CharSequence2 s) { + private void eventuallyLearn(final StringLocated s) { if (learningSub != null) { learningSub.add(s); } @@ -179,7 +177,7 @@ public class SubPreprocessor2 implements ReadFilter { } - private ReadLine getReaderInclude(CharSequence2 s, final File f) { + private ReadLine getReaderInclude(StringLocated s, final File f) { try { if (charset == null) { Log.info("Using default charset"); diff --git a/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java b/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java index a4eb923e0..b5f4b14aa 100644 --- a/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java +++ b/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -59,7 +60,7 @@ public class CommandGanttArrow extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) { final String code1 = arg.get("CODE1", 0); final String code2 = arg.get("CODE2", 0); diff --git a/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java b/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java index c9ec5216b..3ca6833f8 100644 --- a/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java +++ b/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -59,7 +60,7 @@ public class CommandGanttArrow2 extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) { final String name1 = arg.get("TASK1", 0); final String name2 = arg.get("TASK2", 0); diff --git a/src/net/sourceforge/plantuml/project3/CommandPage.java b/src/net/sourceforge/plantuml/project3/CommandPage.java index d76729a6a..8a8b0c99b 100644 --- a/src/net/sourceforge/plantuml/project3/CommandPage.java +++ b/src/net/sourceforge/plantuml/project3/CommandPage.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml.project3; import java.util.List; -import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; diff --git a/src/net/sourceforge/plantuml/project3/CommandSeparator.java b/src/net/sourceforge/plantuml/project3/CommandSeparator.java index 9c54464ca..eaa83391a 100644 --- a/src/net/sourceforge/plantuml/project3/CommandSeparator.java +++ b/src/net/sourceforge/plantuml/project3/CommandSeparator.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ public class CommandSeparator extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) { final String comment = arg.get("COMMENT", 1); diagram.addSeparator(comment); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/project3/ComplementDates.java b/src/net/sourceforge/plantuml/project3/ComplementDates.java index 599927037..2fca91967 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementDates.java +++ b/src/net/sourceforge/plantuml/project3/ComplementDates.java @@ -38,7 +38,6 @@ package net.sourceforge.plantuml.project3; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; -import net.sourceforge.plantuml.command.regex.RegexOr; import net.sourceforge.plantuml.command.regex.RegexResult; public class ComplementDates implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/turing/BFToken.java b/src/net/sourceforge/plantuml/project3/ComplementEmpty.java similarity index 67% rename from src/net/sourceforge/plantuml/turing/BFToken.java rename to src/net/sourceforge/plantuml/project3/ComplementEmpty.java index 476065575..874804789 100644 --- a/src/net/sourceforge/plantuml/turing/BFToken.java +++ b/src/net/sourceforge/plantuml/project3/ComplementEmpty.java @@ -33,43 +33,20 @@ * * */ -package net.sourceforge.plantuml.turing; +package net.sourceforge.plantuml.project3; -public enum BFToken { +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; - NEXT('>'), PREVIOUS('<'), PLUS('+'), MINUS('-'), OUTPUT('.'), - INPUT(','), BRACKET_LEFT('['), BRACKET_RIGHT(']'); +public class ComplementEmpty implements ComplementPattern { - private final char c; - - private BFToken(char c) { - this.c = c; - } - - public char toChar() { - return c; + public IRegex toRegex(String suffix) { + return new RegexLeaf(""); } - public static BFToken getToken(char c) { - switch (c) { - case '>': - return NEXT; - case '<': - return PREVIOUS; - case '+': - return PLUS; - case '-': - return MINUS; - case '.': - return OUTPUT; - case ',': - return INPUT; - case '[': - return BRACKET_LEFT; - case ']': - return BRACKET_RIGHT; - default: - return null; - } + public Failable getComplement(GanttDiagram system, RegexResult arg, String suffix) { + return Failable. ok(new Complement() { + }); } } diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagram.java b/src/net/sourceforge/plantuml/project3/GanttDiagram.java index e0f4b0efc..5261d65af 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project3/GanttDiagram.java @@ -377,11 +377,10 @@ public class GanttDiagram extends AbstractPSystem implements Subject { } private void initMinMax() { - // min = tasks.values().iterator().next().getStart(); if (tasks.size() == 0) { max = min.increment(); } else { - max = tasks.values().iterator().next().getEnd(); + max = null; for (Task task : tasks.values()) { if (task instanceof TaskSeparator) { continue; @@ -391,7 +390,7 @@ public class GanttDiagram extends AbstractPSystem implements Subject { // if (min.compareTo(start) > 0) { // min = start; // } - if (max.compareTo(end) < 0) { + if (max == null || max.compareTo(end) < 0) { max = end; } } @@ -650,4 +649,9 @@ public class GanttDiagram extends AbstractPSystem implements Subject { return CommandExecutionResult.ok(); } + public CommandExecutionResult deleteTask(Task task) { + task.setColors(new ComplementColors(HtmlColorUtils.WHITE, HtmlColorUtils.BLACK)); + return CommandExecutionResult.ok(); + } + } diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java index b3d9a1c83..d8d83b643 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java +++ b/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java @@ -49,11 +49,13 @@ import net.sourceforge.plantuml.core.DiagramType; public class GanttDiagramFactory extends UmlDiagramFactory { - private List subjects() { + static private final List subjects() { return Arrays. asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(), new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource(), new SubjectToday()); } + static private final Collection ALL = getLanguageCommands(); + public GanttDiagramFactory(DiagramType type) { super(type); } @@ -65,9 +67,7 @@ public class GanttDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandNope()); // cmds.add(new CommandComment()); // cmds.add(new CommandMultilinesComment()); - for (Command cmd : getLanguageCommands()) { - cmds.add(cmd); - } + cmds.addAll(ALL); cmds.add(new CommandGanttArrow()); cmds.add(new CommandGanttArrow2()); cmds.add(new CommandSeparator()); @@ -83,7 +83,7 @@ public class GanttDiagramFactory extends UmlDiagramFactory { return cmds; } - private Collection getLanguageCommands() { + private static Collection getLanguageCommands() { final Collection result = new ArrayList(); for (SubjectPattern subject : subjects()) { for (VerbPattern verb : subject.getVerbs()) { diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommand.java b/src/net/sourceforge/plantuml/project3/NaturalCommand.java index f6e05449f..c9173c5c9 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommand.java +++ b/src/net/sourceforge/plantuml/project3/NaturalCommand.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.Command; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -61,7 +62,7 @@ public class NaturalCommand extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(GanttDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(GanttDiagram system, LineLocation location, RegexResult arg) { final Subject subject = subjectPattern.getSubject(system, arg); final Verb verb = verbPattern.getVerb(system, arg); final Failable complement = complementPattern.getComplement(system, arg, "0"); @@ -72,14 +73,24 @@ public class NaturalCommand extends SingleLineCommand2 { } public static Command create(SubjectPattern subject, VerbPattern verb, ComplementPattern complement) { - final RegexConcat pattern = new RegexConcat(// - new RegexLeaf("^"), // - subject.toRegex(), // - new RegexLeaf("[%s]+"), // - verb.toRegex(), // - new RegexLeaf("[%s]+"), // - complement.toRegex("0"), // - new RegexLeaf("$")); + final RegexConcat pattern; + if (complement instanceof ComplementEmpty) { + pattern = new RegexConcat(// + new RegexLeaf("^"), // + subject.toRegex(), // + new RegexLeaf("[%s]+"), // + verb.toRegex(), // + new RegexLeaf("$")); + } else { + pattern = new RegexConcat(// + new RegexLeaf("^"), // + subject.toRegex(), // + new RegexLeaf("[%s]+"), // + verb.toRegex(), // + new RegexLeaf("[%s]+"), // + complement.toRegex("0"), // + new RegexLeaf("$")); + } // System.err.println("NaturalCommand="+pattern.getPattern()); return new NaturalCommand(pattern, subject, verb, complement); } diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java b/src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java index aaf848499..2ce3430bf 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java +++ b/src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.Command; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -67,7 +68,7 @@ public class NaturalCommandAnd extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(GanttDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(GanttDiagram system, LineLocation location, RegexResult arg) { final Subject subject = subjectPattern.getSubject(system, arg); final Verb verb1 = verbPattern1.getVerb(system, arg); final Failable complement1 = complementPattern1.getComplement(system, arg, "1"); diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java b/src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java index e33be06f9..32c5c0ddd 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java +++ b/src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.Command; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -73,7 +74,7 @@ public class NaturalCommandAndAnd extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(GanttDiagram system, RegexResult arg) { + protected CommandExecutionResult executeArg(GanttDiagram system, LineLocation location, RegexResult arg) { final Subject subject = subjectPattern.getSubject(system, arg); final Verb verb1 = verbPattern1.getVerb(system, arg); final Complement complement1 = complementPattern1.getComplement(system, arg, "1").get(); diff --git a/src/net/sourceforge/plantuml/project3/SubjectResource.java b/src/net/sourceforge/plantuml/project3/SubjectResource.java index 8a3f8acb4..e19601dbe 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectResource.java +++ b/src/net/sourceforge/plantuml/project3/SubjectResource.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml.project3; import java.util.Arrays; import java.util.Collection; -import java.util.StringTokenizer; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; diff --git a/src/net/sourceforge/plantuml/project3/SubjectTask.java b/src/net/sourceforge/plantuml/project3/SubjectTask.java index 62eb5a7b2..7f860a4ba 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectTask.java +++ b/src/net/sourceforge/plantuml/project3/SubjectTask.java @@ -47,8 +47,10 @@ import net.sourceforge.plantuml.command.regex.RegexResult; public class SubjectTask implements SubjectPattern { public Collection getVerbs() { - return Arrays. asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(), - new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored()); + return Arrays + . asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(), + new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored(), + new VerbIsDeleted()); } public IRegex toRegex() { diff --git a/src/net/sourceforge/plantuml/project3/Task.java b/src/net/sourceforge/plantuml/project3/Task.java index 2731c221e..0f2e8410f 100644 --- a/src/net/sourceforge/plantuml/project3/Task.java +++ b/src/net/sourceforge/plantuml/project3/Task.java @@ -59,4 +59,9 @@ public interface Task extends Subject, Moment { public void addResource(Resource resource, int percentage); + public void setDiamond(boolean diamond); + + public boolean isDiamond(); + + } diff --git a/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java index 954eccc06..5a865f888 100644 --- a/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java +++ b/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java @@ -90,25 +90,11 @@ public class TaskDrawRegular implements TaskDraw { if (shapeFull instanceof UPolygon) { ug2.draw(shapeFull); } else { - final double fullHeight = ((URectangle) shapeFull).getHeight(); - // ug2.apply(new UChangeBackColor(HtmlColorUtils.WHITE)).apply(new UChangeColor(HtmlColorUtils.WHITE)) - // .draw(shapeFull); - // drawInside(ug1, fullHeight); - // ug2.apply(new UChangeBackColor(null)).draw(shapeFull); + // final double fullHeight = ((URectangle) shapeFull).getHeight(); ug2.draw(shapeFull); } } - // private void drawInside(UGraphic ug, double fullHeight) { - // for (Instant i = task.getStart(); i.compareTo(task.getEnd()) <= 0; i = i.increment()) { - // // final int load = task.getLoadAt(i); - // final URectangle shapeLoad = getShapeInside(i); - // final double diffHeight = fullHeight - shapeLoad.getHeight(); - // final double start = timeScale.getStartingPosition(i); - // ug.apply(new UChangeColor(null)).apply(new UTranslate(start, diffHeight + margin)).draw(shapeLoad); - // } - // } - private UGraphic applyColors(UGraphic ug) { if (colors != null && colors.isOk()) { return colors.apply(ug); @@ -119,20 +105,10 @@ public class TaskDrawRegular implements TaskDraw { return ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UChangeBackColor(defaultColor)); } - private URectangle getShapeInside(Instant instant) { - final double start = timeScale.getStartingPosition(instant); - final double end = timeScale.getEndingPosition(instant); - final double height = getHeight() - 2 * margin; - return new URectangle(end - start, height); - } - - // private URectangle getShapeInside(int load, Instant instant) { + // private URectangle getShapeInside(Instant instant) { // final double start = timeScale.getStartingPosition(instant); // final double end = timeScale.getEndingPosition(instant); - // if (load > 100) { - // load = 100; - // } - // final double height = (getHeight() - 2 * margin) * load / 100.0; + // final double height = getHeight() - 2 * margin; // return new URectangle(end - start, height); // } @@ -149,9 +125,12 @@ public class TaskDrawRegular implements TaskDraw { } private boolean isDiamond() { - final Instant instantStart = task.getStart(); - final Instant instantEnd = task.getEnd(); - return instantStart.compareTo(instantEnd) == 0; + if (task.isDiamond()) { + final Instant instantStart = task.getStart(); + final Instant instantEnd = task.getEnd(); + return instantStart.compareTo(instantEnd) == 0; + } + return false; } private UShape getDiamond() { @@ -162,7 +141,6 @@ public class TaskDrawRegular implements TaskDraw { result.addPoint(h / 2, h); result.addPoint(0, h / 2); return result; - // return result.translate(2, 2); } public double getHeight() { diff --git a/src/net/sourceforge/plantuml/project3/TaskImpl.java b/src/net/sourceforge/plantuml/project3/TaskImpl.java index 7b91a1a0c..f5ed4f63d 100644 --- a/src/net/sourceforge/plantuml/project3/TaskImpl.java +++ b/src/net/sourceforge/plantuml/project3/TaskImpl.java @@ -45,6 +45,7 @@ public class TaskImpl implements Task, LoadPlanable { private final Solver3 solver; private final Map resources2 = new LinkedHashMap(); private final LoadPlanable defaultPlan; + private boolean diamond; public TaskImpl(TaskCode code, LoadPlanable defaultPlan) { this.code = code; @@ -184,4 +185,12 @@ public class TaskImpl implements Task, LoadPlanable { this.resources2.put(resource, percentage); } + public void setDiamond(boolean diamond) { + this.diamond = diamond; + } + + public boolean isDiamond() { + return this.diamond; + } + } diff --git a/src/net/sourceforge/plantuml/project3/TaskSeparator.java b/src/net/sourceforge/plantuml/project3/TaskSeparator.java index e8a9b5f94..093e82221 100644 --- a/src/net/sourceforge/plantuml/project3/TaskSeparator.java +++ b/src/net/sourceforge/plantuml/project3/TaskSeparator.java @@ -96,4 +96,12 @@ public class TaskSeparator implements Task { throw new UnsupportedOperationException(); } + public void setDiamond(boolean diamond) { + throw new UnsupportedOperationException(); + } + + public boolean isDiamond() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/project3/VerbHappens.java b/src/net/sourceforge/plantuml/project3/VerbHappens.java index ac81c9f06..ba647d221 100644 --- a/src/net/sourceforge/plantuml/project3/VerbHappens.java +++ b/src/net/sourceforge/plantuml/project3/VerbHappens.java @@ -65,9 +65,11 @@ public class VerbHappens implements VerbPattern { return CommandExecutionResult.error("No starting date for the project"); } task.setStart(start.asInstantDay(startingDate)); + task.setDiamond(true); } else { final TaskInstant when = (TaskInstant) complement; task.setStart(when.getInstantTheorical()); + task.setDiamond(true); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/project3/VerbIsDeleted.java b/src/net/sourceforge/plantuml/project3/VerbIsDeleted.java new file mode 100644 index 000000000..6b1830d1b --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/VerbIsDeleted.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.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class VerbIsDeleted implements VerbPattern { + + public Collection getComplements() { + return Arrays. asList(new ComplementEmpty()); + } + + public IRegex toRegex() { + return new RegexLeaf("is[%s]+deleted"); + } + + public Verb getVerb(final GanttDiagram project, RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + final Task task = (Task) subject; + return project.deleteTask(task); + } + + }; + } +} diff --git a/src/net/sourceforge/plantuml/salt/Dictionary.java b/src/net/sourceforge/plantuml/salt/Dictionary.java index bf42d8743..158cdb6ad 100644 --- a/src/net/sourceforge/plantuml/salt/Dictionary.java +++ b/src/net/sourceforge/plantuml/salt/Dictionary.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.salt; import java.util.HashMap; import java.util.Map; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.SpriteContainer; @@ -78,8 +79,8 @@ public class Dictionary implements SpriteContainer, ISkinSimple { return 0; } - public boolean useGuillemet() { - return true; + public Guillemet guillemet() { + return Guillemet.GUILLEMET; } public String getMonospacedFamily() { diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java index 5e1950318..d36c64daa 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java @@ -158,10 +158,10 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite { this.setScale(new ScaleSimple(scale)); // System.err.println("skipping " + s); } else if (s.startsWith("sprite $")) { - BlocLines bloc = BlocLines.single(s); + BlocLines bloc = BlocLines.singleString(s); do { s = it.next(); - bloc = bloc.add2(s); + bloc = bloc.addString(s); } while (s.equals("}") == false); final CommandExecutionResult cmdResult = cmd.execute(this, bloc); } else { diff --git a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java index 6134f255c..299c4b402 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java +++ b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java @@ -203,6 +203,8 @@ public abstract class AbstractMessage implements EventWithDeactivate { } private String anchor; + private String anchor1; + private String anchor2; public void setAnchor(String anchor) { this.anchor = anchor; @@ -210,9 +212,26 @@ public abstract class AbstractMessage implements EventWithDeactivate { throw new IllegalArgumentException(anchor); } } + + public void setPart1Anchor(String anchor) { + this.anchor1 = anchor; + } + + public void setPart2Anchor(String anchor) { + this.anchor2 = anchor; + } public String getAnchor() { return anchor; } + + public String getPart1Anchor() { + return this.anchor1; + } + + public String getPart2Anchor() { + return this.anchor2; + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/LinkAnchor.java b/src/net/sourceforge/plantuml/sequencediagram/LinkAnchor.java index d32381415..3262e43b7 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/LinkAnchor.java +++ b/src/net/sourceforge/plantuml/sequencediagram/LinkAnchor.java @@ -40,7 +40,6 @@ import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.activitydiagram3.ftile.Arrows; import net.sourceforge.plantuml.activitydiagram3.ftile.Snake; -import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; diff --git a/src/net/sourceforge/plantuml/sequencediagram/Note.java b/src/net/sourceforge/plantuml/sequencediagram/Note.java index 19e989b2a..d15140046 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/Note.java +++ b/src/net/sourceforge/plantuml/sequencediagram/Note.java @@ -82,6 +82,7 @@ public class Note extends AbstractEvent implements Event, SpecificBackcolorable result.style = this.style; result.url = this.url; result.colors = this.colors; + result.parallel = this.parallel; return result; } @@ -142,4 +143,14 @@ public class Note extends AbstractEvent implements Event, SpecificBackcolorable this.url = url; } + private boolean parallel = false; + + public void goParallel() { + this.parallel = true; + } + + public boolean isParallel() { + return parallel; + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java index 3a11fc18a..5fd2293cf 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -500,7 +500,7 @@ public class SequenceDiagram extends UmlDiagram { final double dpiFactor; final Scale scale = getScale(); if (scale == null) { - dpiFactor = getDpiFactor(fileFormatOption); + dpiFactor = getScaleCoef(fileFormatOption); } else { dpiFactor = scale.getScale(dim.getWidth(), dim.getHeight()); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java index 989d11b79..4e6c3eb52 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -64,7 +65,7 @@ public class CommandActivate extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { final LifeEventType type = LifeEventType.valueOf(StringUtils.goUpperCase(arg.get("TYPE", 0))); final Participant p = diagram.getOrCreateParticipant(StringUtils .eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("WHO", 0))); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java index b3c912438..868ff130e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.sequencediagram.command; import java.util.StringTokenizer; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -64,6 +65,8 @@ import net.sourceforge.plantuml.skin.ArrowPart; public class CommandArrow extends SingleLineCommand2 { + private static final String ANCHOR = "(\\{([\\p{L}0-9_]+)\\}[%s]+)?"; + public CommandArrow() { super(getRegexConcat()); } @@ -75,13 +78,14 @@ public class CommandArrow extends SingleLineCommand2 { static RegexConcat getRegexConcat() { return new RegexConcat( new RegexLeaf("^"), // - new RegexLeaf("PARALLEL", "(&%s*)?"), // - new RegexLeaf("ANCHOR", "(\\{([\\p{L}0-9_]+)\\}[%s]+)?"), // + new RegexLeaf("PARALLEL", "(&[%s]*)?"), // + new RegexLeaf("ANCHOR", ANCHOR), // new RegexOr("PART1", // new RegexLeaf("PART1CODE", "([\\p{L}0-9_.@]+)"), // new RegexLeaf("PART1LONG", "[%g]([^%g]+)[%g]"), // new RegexLeaf("PART1LONGCODE", "[%g]([^%g]+)[%g][%s]*as[%s]+([\\p{L}0-9_.@]+)"), // new RegexLeaf("PART1CODELONG", "([\\p{L}0-9_.@]+)[%s]+as[%s]*[%g]([^%g]+)[%g]")), // + new RegexLeaf("PART1ANCHOR", ANCHOR), // new RegexLeaf("[%s]*"), // new RegexLeaf("ARROW_DRESSING1", "([%s][ox]|(?:[%s][ox])?< { new RegexLeaf("PART2LONG", "[%g]([^%g]+)[%g]"), // new RegexLeaf("PART2LONGCODE", "[%g]([^%g]+)[%g][%s]*as[%s]+([\\p{L}0-9_.@]+)"), // new RegexLeaf("PART2CODELONG", "([\\p{L}0-9_.@]+)[%s]+as[%s]*[%g]([^%g]+)[%g]")), // + new RegexLeaf("PART2ANCHOR", ANCHOR), // new RegexLeaf("[%s]*"), // new RegexLeaf("ACTIVATION", "(?:([+*!-]+)?)"), // new RegexLeaf("[%s]*"), // @@ -140,7 +145,7 @@ public class CommandArrow extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { Participant p1; Participant p2; @@ -235,8 +240,9 @@ public class CommandArrow extends SingleLineCommand2 { if (parallel) { msg.goParallel(); } - final String anchor = arg.get("ANCHOR", 1); - msg.setAnchor(anchor); + msg.setAnchor(arg.get("ANCHOR", 1)); + msg.setPart1Anchor(arg.get("PART1ANCHOR", 1)); + msg.setPart2Anchor(arg.get("PART2ANCHOR", 1)); final String error = diagram.addMessage(msg); if (error != null) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java index a3d722993..079346f28 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.sequencediagram.command; import java.text.DecimalFormat; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -63,7 +64,7 @@ public class CommandAutonumber extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { DottedNumber start = DottedNumber.create("1"); final String arg0 = arg.get("START", 0); // System.err.println("arg0=" + arg0); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumberIncrement.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumberIncrement.java index e75e17933..1dca272b2 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumberIncrement.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumberIncrement.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -60,7 +61,7 @@ public class CommandAutonumberIncrement extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { final String df = arg.get("DF", 0); DecimalFormat decimalFormat = null; diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java index ea823c6df..27595d77e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -43,7 +44,6 @@ import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexOr; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Display; -import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.color.ColorParser; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.Colors; @@ -72,7 +72,7 @@ public class CommandBoxStart extends SingleLineCommand2 { @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg2) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg2) { if (diagram.isBoxPending()) { return CommandExecutionResult.error("Box cannot be nested"); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java index a98f03407..db3388ec3 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandDeactivateShort extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(SequenceDiagram sequenceDiagram, RegexResult arg2) { + protected CommandExecutionResult executeArg(SequenceDiagram sequenceDiagram, LineLocation location, RegexResult arg2) { Message message = sequenceDiagram.getActivatingMessage(); if (message == null) { return CommandExecutionResult.error("Nothing to deactivate."); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java index 4a12de479..89cd1c950 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -63,7 +64,7 @@ abstract class CommandExoArrowAny extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { final String body = arg.getLazzy("ARROW_BODYA", 0) + arg.getLazzy("ARROW_BODYB", 0); final String dressing = arg.getLazzy("ARROW_DRESSING", 0); final Participant p = diagram.getOrCreateParticipant(StringUtils diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java index 1538787b6..ea05b0846 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.sequencediagram.command; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -65,7 +66,7 @@ public class CommandGrouping extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { String type = StringUtils.goLowerCase(arg.get("TYPE", 0)); final HtmlColor backColorElement = diagram.getSkinParam().getIHtmlColorSet() .getColorIfValid(arg.get("COLORS", 0)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandLinkAnchor.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandLinkAnchor.java index df520172f..899a09f79 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandLinkAnchor.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandLinkAnchor.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.sequencediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -60,7 +61,7 @@ public class CommandLinkAnchor extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(SequenceDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { final String anchor1 = arg.get("ANCHOR1", 0); final String anchor2 = arg.get("ANCHOR2", 0); final String message = arg.get("MESSAGE", 0); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java index fbdf6b8f1..26f9fce28 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.sequencediagram.command; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -75,7 +76,7 @@ public abstract class CommandParticipant extends SingleLineCommand2 line0 = StringUtils.getSplit(getStartingPattern(), StringUtils.trin(lines.getFirst499())); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.getFirst499().getStringTrimmed()); final HtmlColor backColorElement = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get(0)); // final HtmlColor backColorGeneral = HtmlColorSet.getInstance().getColorIfValid(line0.get(1)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java index aa0881eb9..d3a4a4533 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.sequencediagram.command; import java.util.ArrayList; import java.util.List; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -69,7 +70,7 @@ public class CommandReferenceOverSeveral extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(SequenceDiagram sequenceDiagram, RegexResult arg) { + protected CommandExecutionResult executeArg(SequenceDiagram sequenceDiagram, LineLocation location, RegexResult arg) { Message message1 = sequenceDiagram.getActivatingMessage(); boolean doDeactivation = true; diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java index 1e7e114b9..c090b1e96 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java @@ -40,13 +40,14 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.sequencediagram.InGroupable; import net.sourceforge.plantuml.sequencediagram.NotePosition; import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.rose.AbstractComponentRoseArrow; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.ugraphic.UGraphic; abstract class Arrow extends GraphicalElement implements InGroupable { private final Rose skin; - private final Component arrowComponent; + private final AbstractComponentRoseArrow arrowComponent; private double paddingArrowHead; private double maxX; private final Url url; @@ -67,7 +68,7 @@ abstract class Arrow extends GraphicalElement implements InGroupable { public abstract double getActualWidth(StringBounder stringBounder); - Arrow(double startingY, Rose skin, Component arrowComponent, Url url) { + Arrow(double startingY, Rose skin, AbstractComponentRoseArrow arrowComponent, Url url) { super(startingY); this.skin = skin; this.arrowComponent = arrowComponent; @@ -96,7 +97,7 @@ abstract class Arrow extends GraphicalElement implements InGroupable { return skin; } - protected final Component getArrowComponent() { + protected final AbstractComponentRoseArrow getArrowComponent() { return arrowComponent; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java index d59f08f36..680befa80 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java @@ -45,6 +45,7 @@ import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.Component; 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.UTranslate; @@ -55,7 +56,7 @@ class MessageArrow extends Arrow { private final LivingParticipantBox p2; private final Component compAliveBox; - public MessageArrow(double startingY, Rose skin, Component arrow, LivingParticipantBox p1, LivingParticipantBox p2, + public MessageArrow(double startingY, Rose skin, AbstractComponentRoseArrow arrow, LivingParticipantBox p1, LivingParticipantBox p2, Url url, Component compAliveBox) { super(startingY, skin, arrow, url); @@ -151,7 +152,7 @@ class MessageArrow extends Arrow { @Override public double getArrowYStartLevel(StringBounder stringBounder) { if (getArrowComponent() instanceof ArrowComponent) { - final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final AbstractComponentRoseArrow arrowComponent = (AbstractComponentRoseArrow) getArrowComponent(); final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), arrowComponent.getPreferredHeight(stringBounder)); return getStartingY() + arrowComponent.getStartPoint(stringBounder, dim).getY(); @@ -162,7 +163,7 @@ class MessageArrow extends Arrow { @Override public double getArrowYEndLevel(StringBounder stringBounder) { if (getArrowComponent() instanceof ArrowComponent) { - final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final AbstractComponentRoseArrow arrowComponent = (AbstractComponentRoseArrow) getArrowComponent(); final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), arrowComponent.getPreferredHeight(stringBounder)); return getStartingY() + arrowComponent.getEndPoint(stringBounder, dim).getY(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java index 6cea31089..ecfe01868 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java @@ -46,8 +46,8 @@ import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.ArrowDecoration; -import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.rose.AbstractComponentRoseArrow; import net.sourceforge.plantuml.skin.rose.ComponentRoseArrow; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -60,7 +60,7 @@ public class MessageExoArrow extends Arrow { private final boolean shortArrow; private final ArrowConfiguration arrowConfiguration; - public MessageExoArrow(double startingY, Rose skin, Component arrow, LivingParticipantBox p, MessageExoType type, + public MessageExoArrow(double startingY, Rose skin, AbstractComponentRoseArrow arrow, LivingParticipantBox p, MessageExoType type, Url url, boolean shortArrow, ArrowConfiguration arrowConfiguration) { super(startingY, skin, arrow, url); this.p = p; @@ -163,7 +163,7 @@ public class MessageExoArrow extends Arrow { @Override public double getArrowYStartLevel(StringBounder stringBounder) { if (getArrowComponent() instanceof ArrowComponent) { - final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final AbstractComponentRoseArrow arrowComponent = (AbstractComponentRoseArrow) getArrowComponent(); final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), arrowComponent.getPreferredHeight(stringBounder)); return getStartingY() + arrowComponent.getStartPoint(stringBounder, dim).getY(); @@ -174,7 +174,7 @@ public class MessageExoArrow extends Arrow { @Override public double getArrowYEndLevel(StringBounder stringBounder) { if (getArrowComponent() instanceof ArrowComponent) { - final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final AbstractComponentRoseArrow arrowComponent = (AbstractComponentRoseArrow) getArrowComponent(); final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), arrowComponent.getPreferredHeight(stringBounder)); return getStartingY() + arrowComponent.getEndPoint(stringBounder, dim).getY(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java index e53096463..ce82dec38 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java @@ -43,8 +43,8 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.sequencediagram.NotePosition; import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.ArrowComponent; -import net.sourceforge.plantuml.skin.Component; 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.UTranslate; @@ -55,7 +55,7 @@ class MessageSelfArrow extends Arrow { private final double deltaX; private final double deltaY; - public MessageSelfArrow(double startingY, Rose skin, Component arrow, LivingParticipantBox p1, double deltaY, + public MessageSelfArrow(double startingY, Rose skin, AbstractComponentRoseArrow arrow, LivingParticipantBox p1, double deltaY, Url url, double deltaX) { super(startingY, skin, arrow, url); this.p1 = p1; @@ -105,7 +105,7 @@ class MessageSelfArrow extends Arrow { @Override public double getArrowYStartLevel(StringBounder stringBounder) { if (getArrowComponent() instanceof ArrowComponent) { - final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final AbstractComponentRoseArrow arrowComponent = (AbstractComponentRoseArrow) getArrowComponent(); final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), arrowComponent.getPreferredHeight(stringBounder)); return getStartingY() + arrowComponent.getStartPoint(stringBounder, dim).getY(); @@ -116,7 +116,7 @@ class MessageSelfArrow extends Arrow { @Override public double getArrowYEndLevel(StringBounder stringBounder) { if (getArrowComponent() instanceof ArrowComponent) { - final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final AbstractComponentRoseArrow arrowComponent = (AbstractComponentRoseArrow) getArrowComponent(); final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), arrowComponent.getPreferredHeight(stringBounder)); return getStartingY() + arrowComponent.getEndPoint(stringBounder, dim).getY(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java index ec0211c17..dc0b3ddcb 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java @@ -174,7 +174,7 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker { scale = getScale(area.getWidth(), area.getHeight()); - final double dpiFactor = diagram.getDpiFactor(fileFormatOption); + final double dpiFactor = diagram.getScaleCoef(fileFormatOption); // System.err.println("dpiFactor=" + dpiFactor); // System.err.println("scale=" + scale); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java index 5809cb275..8c27f84bd 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java @@ -52,6 +52,7 @@ import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.ArrowHead; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.rose.AbstractComponentRoseArrow; class Step1Message extends Step1Abstract { @@ -69,7 +70,7 @@ class Step1Message extends Step1Abstract { if (isSelfMessage()) { this.messageArrow = null; } else { - final Component comp = drawingSet.getSkin().createComponent(ComponentType.ARROW, getConfig(), + final AbstractComponentRoseArrow comp = drawingSet.getSkin().createComponentArrow(getConfig(), drawingSet.getSkinParam(), message.getLabelNumbered()); final Component compAliveBox = drawingSet.getSkin().createComponent(ComponentType.ALIVE_BOX_OPEN_OPEN, null, drawingSet.getSkinParam(), null); @@ -205,8 +206,8 @@ class Step1Message extends Step1Abstract { deltaY += getHalfLifeWidth(); } - return new MessageSelfArrow(posY, getDrawingSet().getSkin(), getDrawingSet().getSkin().createComponent( - ComponentType.ARROW, getConfig(), getDrawingSet().getSkinParam(), getMessage().getLabelNumbered()), + return new MessageSelfArrow(posY, getDrawingSet().getSkin(), getDrawingSet().getSkin().createComponentArrow( + getConfig(), getDrawingSet().getSkinParam(), getMessage().getLabelNumbered()), getLivingParticipantBox1(), deltaY, getMessage().getUrl(), deltaX); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java index 009784347..7316a1c29 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java @@ -59,9 +59,9 @@ class Step1MessageExo extends Step1Abstract { setConfig(getArrowType(message)); this.messageArrow = new MessageExoArrow(freeY.getFreeY(range), drawingSet.getSkin(), drawingSet.getSkin() - .createComponent(ComponentType.ARROW, getConfig(), drawingSet.getSkinParam(), - message.getLabelNumbered()), getLivingParticipantBox(), message.getType(), message.getUrl(), - message.isShortArrow(), message.getArrowConfiguration()); + .createComponentArrow(getConfig(), drawingSet.getSkinParam(), message.getLabelNumbered()), + getLivingParticipantBox(), message.getType(), message.getUrl(), message.isShortArrow(), + message.getArrowConfiguration()); final List noteOnMessages = message.getNoteOnMessages(); for (Note noteOnMessage : noteOnMessages) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java index 3242b4285..b19712f3c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java @@ -44,11 +44,11 @@ import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.MessageExo; import net.sourceforge.plantuml.sequencediagram.MessageExoType; import net.sourceforge.plantuml.skin.Area; -import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.ArrowDecoration; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.rose.AbstractComponentRoseArrow; import net.sourceforge.plantuml.skin.rose.ComponentRoseArrow; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -81,12 +81,12 @@ public class CommunicationExoTile extends AbstractTile implements TileWithUpdate } - private ArrowComponent getComponent(StringBounder stringBounder) { + private AbstractComponentRoseArrow getComponent(StringBounder stringBounder) { ArrowConfiguration arrowConfiguration = message.getArrowConfiguration(); if (message.getType().getDirection() == -1) { arrowConfiguration = arrowConfiguration.reverse(); } - final ArrowComponent comp = skin + final AbstractComponentRoseArrow comp = skin .createComponentArrow(arrowConfiguration, skinParam, message.getLabelNumbered()); return comp; } @@ -167,7 +167,7 @@ public class CommunicationExoTile extends AbstractTile implements TileWithUpdate } public void updateStairs(StringBounder stringBounder, double y) { - final ArrowComponent comp = (ArrowComponent) getComponent(stringBounder); + final AbstractComponentRoseArrow comp = getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); final double arrowY = comp.getStartPoint(stringBounder, dim).getY(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java index e586e34f5..a3e137152 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java @@ -45,10 +45,10 @@ import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.Message; import net.sourceforge.plantuml.skin.Area; -import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.Component; 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.UTranslate; @@ -104,7 +104,7 @@ public class CommunicationTile extends AbstractTile implements TileWithUpdateSta return message.isCreate(); } - private ArrowComponent getComponent(StringBounder stringBounder) { + private AbstractComponentRoseArrow getComponent(StringBounder stringBounder) { ArrowConfiguration arrowConfiguration = message.getArrowConfiguration(); /* * if (isSelf()) { arrowConfiguration = arrowConfiguration.self(); } else @@ -113,8 +113,8 @@ public class CommunicationTile extends AbstractTile implements TileWithUpdateSta arrowConfiguration = arrowConfiguration.reverse(); } - final ArrowComponent comp = skin - .createComponentArrow(arrowConfiguration, skinParam, message.getLabelNumbered()); + final AbstractComponentRoseArrow comp = skin.createComponentArrow(arrowConfiguration, skinParam, + message.getLabelNumbered()); return comp; } @@ -126,7 +126,7 @@ public class CommunicationTile extends AbstractTile implements TileWithUpdateSta public static final double LIVE_DELTA_SIZE = 5; public void updateStairs(StringBounder stringBounder, double y) { - final ArrowComponent comp = (ArrowComponent) getComponent(stringBounder); + final AbstractComponentRoseArrow comp = (AbstractComponentRoseArrow) getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); // final Point2D p2 = comp.getEndPoint(stringBounder, dim); // System.err.println("CommunicationTile::updateStairs y=" + y + " p1=" + p1 + " p2=" + p2 + " dim=" + dim); @@ -139,8 +139,13 @@ public class CommunicationTile extends AbstractTile implements TileWithUpdateSta } public void drawU(UGraphic ug) { + final String anchor1 = message.getPart1Anchor(); + final String anchor2 = message.getPart2Anchor(); + if (anchor1 != null || anchor2 != null) { + return; + } final StringBounder stringBounder = ug.getStringBounder(); - final Component comp = getComponent(stringBounder); + final AbstractComponentRoseArrow comp = getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); double x1 = getPoint1(stringBounder).getCurrentValue(); double x2 = getPoint2(stringBounder).getCurrentValue(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java index 2543dfdac..f46791aaa 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java @@ -46,11 +46,10 @@ import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.Message; import net.sourceforge.plantuml.skin.Area; -import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.Component; -import net.sourceforge.plantuml.skin.ComponentType; 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.UTranslate; @@ -67,6 +66,11 @@ public class CommunicationTileSelf extends AbstractTile implements TileWithUpdat return message; } + @Override + public double getYPoint(StringBounder stringBounder) { + return getComponent(stringBounder).getYPoint(stringBounder); + } + public CommunicationTileSelf(LivingSpace livingSpace1, Message message, Rose skin, ISkinParam skinParam, LivingSpaces livingSpaces) { this.livingSpace1 = livingSpace1; @@ -86,16 +90,16 @@ public class CommunicationTileSelf extends AbstractTile implements TileWithUpdat // // } - private Component getComponent(StringBounder stringBounder) { + private AbstractComponentRoseArrow getComponent(StringBounder stringBounder) { ArrowConfiguration arrowConfiguration = message.getArrowConfiguration(); arrowConfiguration = arrowConfiguration.self(); - final Component comp = skin.createComponent(ComponentType.ARROW, arrowConfiguration, skinParam, - message.getLabelNumbered()); + final AbstractComponentRoseArrow comp = skin + .createComponentArrow(arrowConfiguration, skinParam, message.getLabelNumbered()); return comp; } public void updateStairs(StringBounder stringBounder, double y) { - final ArrowComponent comp = (ArrowComponent) getComponent(stringBounder); + final AbstractComponentRoseArrow comp = getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); final Point2D p1 = comp.getStartPoint(stringBounder, dim); final Point2D p2 = comp.getEndPoint(stringBounder, dim); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java index 69ca895a5..a5ee42e43 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java @@ -62,6 +62,11 @@ public class CommunicationTileSelfNoteRight extends AbstractTile implements Tile public Event getEvent() { return message; } + + @Override + public double getYPoint(StringBounder stringBounder) { + return tile.getYPoint(stringBounder); + } public CommunicationTileSelfNoteRight(CommunicationTileSelf tile, Message message, Rose skin, ISkinParam skinParam, Note noteOnMessage) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java index 4d590e92e..94e64a807 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.sequencediagram.teoz; -import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.ColorMapper; @@ -43,7 +42,6 @@ import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; -import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UParamNull; diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java index 78b0c1585..15b639841 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java @@ -64,10 +64,10 @@ public class NoteTile extends AbstractTile implements Tile { public Event getEvent() { return note; } - + @Override public double getYPoint(StringBounder stringBounder) { - return 0; + return getComponent(stringBounder).getPreferredHeight(stringBounder) / 2; } public NoteTile(LivingSpace livingSpace1, LivingSpace livingSpace2, Note note, Rose skin, ISkinParam skinParam) { diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java index 4c619591c..b1543d614 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNoteHexagonal.java @@ -36,7 +36,6 @@ package net.sourceforge.plantuml.skin.rose; import net.sourceforge.plantuml.ISkinSimple; -import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; diff --git a/src/net/sourceforge/plantuml/skin/rose/Rose.java b/src/net/sourceforge/plantuml/skin/rose/Rose.java index 27d8046da..a481c3662 100644 --- a/src/net/sourceforge/plantuml/skin/rose/Rose.java +++ b/src/net/sourceforge/plantuml/skin/rose/Rose.java @@ -48,8 +48,8 @@ import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.SkinParameter; import net.sourceforge.plantuml.graphic.SymbolContext; -import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.ArrowDirection; import net.sourceforge.plantuml.skin.Component; @@ -244,8 +244,9 @@ public class Rose { } if (type == ComponentType.DIVIDER) { return new ComponentRoseDivider(getUFont2(param, FontParam.SEQUENCE_DIVIDER), getHtmlColor(param, - ColorParam.sequenceDividerBackground), stringsToDisplay, param, deltaShadow(param) > 0, getStroke( - param, LineParam.sequenceDividerBorder, 2), getHtmlColor(param, ColorParam.sequenceDividerBorder)); + ColorParam.sequenceDividerBackground), stringsToDisplay, param, deltaShadow(param, + ColorParam.sequenceDividerBackground) > 0, getStroke(param, LineParam.sequenceDividerBorder, 2), + getHtmlColor(param, ColorParam.sequenceDividerBorder)); } if (type == ComponentType.REFERENCE) { return new ComponentRoseReference(getUFont2(param, FontParam.SEQUENCE_REFERENCE), getSymbolContext(param, @@ -269,8 +270,7 @@ public class Rose { return null; } - public ArrowComponent createComponentArrow(ArrowConfiguration config, ISkinParam param, - Display stringsToDisplay) { + public AbstractComponentRoseArrow createComponentArrow(ArrowConfiguration config, ISkinParam param, Display stringsToDisplay) { final HtmlColor sequenceArrow = config.getColor() == null ? getHtmlColor(param, ColorParam.arrow) : config .getColor(); if (config.getArrowDirection() == ArrowDirection.SELF) { @@ -286,68 +286,76 @@ public class Rose { param.strictUmlStyle() == false, param.responseMessageBelowArrow()); } - private double deltaShadow(ISkinParam param) { - return param.shadowing(null) ? 4.0 : 0; + private double deltaShadow(ISkinParam param, ColorParam color) { + SkinParameter skinParameter = null; + if (color == ColorParam.participantBorder) { + skinParameter = SkinParameter.PARTICIPANT; + } else if (color == ColorParam.actorBorder) { + skinParameter = SkinParameter.ACTOR; + } + final boolean result = skinParameter == null ? param.shadowing(null) : param.shadowing2(null, skinParameter); + return result ? 4.0 : 0; } - private SymbolContext getSymbolContext(ISkinParam param, ColorParam color) { + private SymbolContext getSymbolContext(ISkinParam skin, ColorParam color) { if (color == ColorParam.participantBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.participantBackground), getHtmlColor(param, - ColorParam.participantBorder)).withStroke( - getStroke(param, LineParam.sequenceParticipantBorder, 1.5)).withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.participantBackground), getHtmlColor(skin, + ColorParam.participantBorder)) + .withStroke(getStroke(skin, LineParam.sequenceParticipantBorder, 1.5)).withDeltaShadow( + deltaShadow(skin, color)); } if (color == ColorParam.actorBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.actorBackground), getHtmlColor(param, - ColorParam.actorBorder)).withStroke(getStroke(param, LineParam.sequenceActorBorder, 2)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.actorBackground), getHtmlColor(skin, + ColorParam.actorBorder)).withStroke(getStroke(skin, LineParam.sequenceActorBorder, 2)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.boundaryBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.boundaryBackground), getHtmlColor(param, - ColorParam.boundaryBorder)).withStroke(getStroke(param, LineParam.sequenceActorBorder, 2)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.boundaryBackground), getHtmlColor(skin, + ColorParam.boundaryBorder)).withStroke(getStroke(skin, LineParam.sequenceActorBorder, 2)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.controlBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.controlBackground), getHtmlColor(param, - ColorParam.controlBorder)).withStroke(getStroke(param, LineParam.sequenceActorBorder, 2)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.controlBackground), getHtmlColor(skin, + ColorParam.controlBorder)).withStroke(getStroke(skin, LineParam.sequenceActorBorder, 2)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.collectionsBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.collectionsBackground), getHtmlColor(param, - ColorParam.collectionsBorder)).withStroke(getStroke(param, LineParam.sequenceActorBorder, 1.5)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.collectionsBackground), getHtmlColor(skin, + ColorParam.collectionsBorder)).withStroke(getStroke(skin, LineParam.sequenceActorBorder, 1.5)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.entityBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.entityBackground), getHtmlColor(param, - ColorParam.entityBorder)).withStroke(getStroke(param, LineParam.sequenceActorBorder, 2)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.entityBackground), getHtmlColor(skin, + ColorParam.entityBorder)).withStroke(getStroke(skin, LineParam.sequenceActorBorder, 2)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.databaseBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.databaseBackground), getHtmlColor(param, - ColorParam.databaseBorder)).withStroke(getStroke(param, LineParam.sequenceActorBorder, 2)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.databaseBackground), getHtmlColor(skin, + ColorParam.databaseBorder)).withStroke(getStroke(skin, LineParam.sequenceActorBorder, 2)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.sequenceLifeLineBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.sequenceLifeLineBackground), getHtmlColor(param, - ColorParam.sequenceLifeLineBorder)).withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.sequenceLifeLineBackground), getHtmlColor(skin, + ColorParam.sequenceLifeLineBorder)).withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.noteBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.noteBackground), getHtmlColor(param, - ColorParam.noteBorder)).withStroke(getStroke(param, LineParam.noteBorder, 1)).withDeltaShadow( - deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.noteBackground), getHtmlColor(skin, + ColorParam.noteBorder)).withStroke(getStroke(skin, LineParam.noteBorder, 1)).withDeltaShadow( + deltaShadow(skin, color)); } if (color == ColorParam.sequenceGroupBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.sequenceGroupBackground), getHtmlColor(param, - ColorParam.sequenceGroupBorder)).withStroke(getStroke(param, LineParam.sequenceGroupBorder, 2)) - .withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.sequenceGroupBackground), getHtmlColor(skin, + ColorParam.sequenceGroupBorder)).withStroke(getStroke(skin, LineParam.sequenceGroupBorder, 2)) + .withDeltaShadow(deltaShadow(skin, color)); } if (color == ColorParam.sequenceBoxBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.sequenceBoxBackground), getHtmlColor(param, + return new SymbolContext(getHtmlColor(skin, ColorParam.sequenceBoxBackground), getHtmlColor(skin, ColorParam.sequenceBoxBorder)); } if (color == ColorParam.sequenceReferenceBorder) { - return new SymbolContext(getHtmlColor(param, ColorParam.sequenceReferenceHeaderBackground), getHtmlColor( - param, ColorParam.sequenceReferenceBorder)).withStroke( - getStroke(param, LineParam.sequenceReferenceBorder, 2)).withDeltaShadow(deltaShadow(param)); + return new SymbolContext(getHtmlColor(skin, ColorParam.sequenceReferenceHeaderBackground), getHtmlColor( + skin, ColorParam.sequenceReferenceBorder)).withStroke( + getStroke(skin, LineParam.sequenceReferenceBorder, 2)).withDeltaShadow(deltaShadow(skin, color)); } throw new IllegalArgumentException(); } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java b/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java index 3695af194..60398ddab 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.statediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -62,7 +63,7 @@ public class CommandAddField extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(StateDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.getLazzy("CODE", 0); final String field = arg.get("FIELD", 0); diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java index d694c0c8e..9e0753546 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.statediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -95,7 +96,7 @@ public class CommandCreatePackageState extends SingleLineCommand2 } @Override - protected CommandExecutionResult executeArg(StateDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { final IGroup currentPackage = diagram.getCurrentGroup(); final Code code = Code.of(getNotNull(arg, "CODE1", "CODE2")); String display = getNotNull(arg, "DISPLAY1", "DISPLAY2"); diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java index b4e2a20ec..47cfe0be8 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.statediagram.command; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -94,7 +95,7 @@ public class CommandCreateState extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(StateDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { final Code code = Code.of(arg.getLazzy("CODE", 0)); String display = arg.getLazzy("DISPLAY", 0); if (display == null) { diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java index 82a7cf507..7073e6ecf 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.statediagram.command; import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -88,7 +89,7 @@ public class CommandLinkState extends SingleLineCommand2 { } @Override - protected CommandExecutionResult executeArg(StateDiagram diagram, RegexResult arg) { + protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { final String ent1 = arg.get("ENT1", 0); final String ent2 = arg.get("ENT2", 0); diff --git a/src/net/sourceforge/plantuml/suggest/SuggestEngine.java b/src/net/sourceforge/plantuml/suggest/SuggestEngine.java index 23b82e798..b06864e75 100644 --- a/src/net/sourceforge/plantuml/suggest/SuggestEngine.java +++ b/src/net/sourceforge/plantuml/suggest/SuggestEngine.java @@ -35,18 +35,12 @@ */ package net.sourceforge.plantuml.suggest; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.CharSequence2; -import net.sourceforge.plantuml.CharSequence2Impl; import net.sourceforge.plantuml.command.UmlDiagramFactory; import net.sourceforge.plantuml.core.UmlSource; -import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.version.IteratorCounter2; -import net.sourceforge.plantuml.version.IteratorCounter2Impl; final public class SuggestEngine { @@ -61,12 +55,12 @@ final public class SuggestEngine { } public SuggestEngine(UmlSource source, UmlDiagramFactory systemFactory) { - this.systemFactory = systemFactory; - this.it99 = source.iterator2(); - final CharSequence startLine = it99.next(); - if (StartUtils.isArobaseStartDiagram(startLine) == false) { +// 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) { @@ -152,15 +146,16 @@ final public class SuggestEngine { } private IteratorCounter2 replaceFirstLine(String s) { - final List tmp = new ArrayList(); - tmp.add(new CharSequence2Impl(s, null)); - final Iterator it3 = it99.cloneMe(); - if (it3.hasNext()) { - it3.next(); - } - while (it3.hasNext()) { - tmp.add(new CharSequence2Impl(it3.next(), null)); - } - return new IteratorCounter2Impl(tmp); + 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/svek/CucaDiagramFileMakerSvek.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java index d29da85ba..f649e5bfd 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java @@ -161,7 +161,7 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { final double scale; final Scale diagScale = diagram.getScale(); if (diagScale == null) { - scale = diagram.getDpiFactor(fileFormatOption); + scale = diagram.getScaleCoef(fileFormatOption); } else { scale = diagScale.getScale(dim.getWidth(), dim.getHeight()); } diff --git a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java index 08b4d8ed2..dc65942d5 100644 --- a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java +++ b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java @@ -48,6 +48,7 @@ import java.util.regex.Pattern; import net.sourceforge.plantuml.BaseFile; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; @@ -120,7 +121,6 @@ import net.sourceforge.plantuml.svek.image.EntityImageStateEmptyDescription; import net.sourceforge.plantuml.svek.image.EntityImageSynchroBar; import net.sourceforge.plantuml.svek.image.EntityImageTips; import net.sourceforge.plantuml.svek.image.EntityImageUseCase; -import net.sourceforge.plantuml.ugraphic.sprite.Sprite; public final class GeneralImageBuilder { @@ -356,7 +356,7 @@ public final class GeneralImageBuilder { if (isHideEmptyDescriptionForState && leaf.getBodier().getFieldsToDisplay().size() == 0) { return new EntityImageStateEmptyDescription(leaf, skinParam); } - if (leaf.getStereotype() != null && "<>".equals(leaf.getStereotype().getLabel(false))) { + if (leaf.getStereotype() != null && "<>".equals(leaf.getStereotype().getLabel(Guillemet.DOUBLE_COMPARATOR))) { return new EntityImageState2(leaf, skinParam); } return new EntityImageState(leaf, skinParam); @@ -554,9 +554,8 @@ public final class GeneralImageBuilder { if (legend == null || legend.isNull()) { return original; } - final TextBlock text = EntityImageLegend.create(legend.getDisplay(), dotData.getSkinParam()); - - return DecorateEntityImage.add(original, text, legend.getHorizontalAlignment(), legend.getVerticalAlignment()); + final TextBlock legendBlock = EntityImageLegend.create(legend.getDisplay(), dotData.getSkinParam()); + return DecorateEntityImage.add(legendBlock, original, legend.getHorizontalAlignment(), legend.getVerticalAlignment()); } private TextBlock getStereoBlock(IGroup g) { @@ -566,7 +565,7 @@ public final class GeneralImageBuilder { private TextBlock getStereoBlockWithoutLegend(IGroup g) { final Stereotype stereotype = g.getStereotype(); - final DisplayPositionned legend = g.getLegend(); + // final DisplayPositionned legend = g.getLegend(); if (stereotype == null) { return TextBlockUtils.empty(0, 0); } @@ -575,7 +574,7 @@ public final class GeneralImageBuilder { return tmp; } - final List stereos = stereotype.getLabels(dotData.getSkinParam().useGuillemet()); + final List stereos = stereotype.getLabels(dotData.getSkinParam().guillemet()); if (stereos == null) { return TextBlockUtils.empty(0, 0); } diff --git a/src/net/sourceforge/plantuml/svek/GraphvizCrash.java b/src/net/sourceforge/plantuml/svek/GraphvizCrash.java index c51ed366b..70af5589a 100644 --- a/src/net/sourceforge/plantuml/svek/GraphvizCrash.java +++ b/src/net/sourceforge/plantuml/svek/GraphvizCrash.java @@ -128,7 +128,7 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage { private List init() { final List strings = anErrorHasOccured(null, text); - strings.add("For some reason, dot/Graphviz has crashed."); + strings.add("For some reason, dot/GraphViz has crashed."); strings.add("This has been generated with PlantUML (" + Version.versionString() + ")."); checkOldVersionWarning(strings); strings.add(" "); diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index bfe2a7799..98e6f5612 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; import java.util.Collection; import java.util.List; +import java.util.Set; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; @@ -637,7 +638,7 @@ public class Line implements Moveable, Hideable { } - public void drawU(UGraphic ug, HtmlColor color) { + public void drawU(UGraphic ug, HtmlColor color, Set ids) { if (opale) { return; } @@ -700,7 +701,10 @@ public class Line implements Moveable, Hideable { } } - todraw.setComment(link.getEntity1().getCode().getFullName() + "-" + link.getEntity2().getCode().getFullName()); + final String comment = link.getEntity1().getCode().getFullName() + "-" + + link.getEntity2().getCode().getFullName(); + todraw.setComment(uniq(ids, comment)); + drawRainbow(ug.apply(new UTranslate(x, y)), color, todraw, link.getSupplementaryColors(), stroke); ug = ug.apply(new UStroke()).apply(new UChangeColor(color)); @@ -733,7 +737,24 @@ public class Line implements Moveable, Hideable { } } - private void drawRainbow(UGraphic ug, HtmlColor color, DotPath todraw, List supplementaryColors, UStroke stroke) { + private String uniq(final Set ids, final String comment) { + boolean changed = ids.add(comment); + if (changed) { + return comment; + } + int i = 1; + while (true) { + final String candidate = comment + "-" + i; + changed = ids.add(candidate); + if (changed) { + return candidate; + } + i++; + } + } + + private void drawRainbow(UGraphic ug, HtmlColor color, DotPath todraw, List supplementaryColors, + UStroke stroke) { ug.draw(todraw); final LinkType linkType = link.getType(); diff --git a/src/net/sourceforge/plantuml/svek/SvekResult.java b/src/net/sourceforge/plantuml/svek/SvekResult.java index e3d9ad008..aa216e01e 100644 --- a/src/net/sourceforge/plantuml/svek/SvekResult.java +++ b/src/net/sourceforge/plantuml/svek/SvekResult.java @@ -36,6 +36,8 @@ package net.sourceforge.plantuml.svek; import java.awt.geom.Dimension2D; +import java.util.HashSet; +import java.util.Set; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.UmlDiagramType; @@ -72,8 +74,8 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage, cluster.drawU(ug, new UStroke(1.5), dotData.getUmlDiagramType(), dotData.getSkinParam()); } - final HtmlColor color = HtmlColorUtils.noGradient(rose.getHtmlColor(dotData.getSkinParam(), - null, getArrowColorParam())); + final HtmlColor color = HtmlColorUtils.noGradient(rose.getHtmlColor(dotData.getSkinParam(), null, + getArrowColorParam())); for (Shape shape : dotStringFactory.getBibliotekon().allShapes()) { final double minX = shape.getMinX(); @@ -87,9 +89,11 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage, // shape.getImage().drawNeighborhood(ug2, minX, minY); } + final Set ids = new HashSet(); + for (Line line : dotStringFactory.getBibliotekon().allLines()) { final UGraphic ug2 = line.isHidden() ? ug.apply(UHidden.HIDDEN) : ug; - line.drawU(ug2, color); + line.drawU(ug2, color, ids); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java b/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java index 200bbd828..f5b5d157a 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageArcCircle.java @@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.ILeaf; @@ -67,10 +68,10 @@ public class EntityImageArcCircle extends AbstractEntityImage { this.name = entity.getDisplay().create(new FontConfiguration(getSkinParam(), FontParam.COMPONENT, stereotype), HorizontalAlignment.CENTER, skinParam); - if (stereotype == null || stereotype.getLabel(false) == null) { + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { this.stereo = null; } else { - this.stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().useGuillemet())).create( + this.stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.COMPONENT_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java index d95ae0ad1..47d10ffdd 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClassHeader2.java @@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.cucadiagram.Display; @@ -100,12 +101,12 @@ public class EntityImageClassHeader2 extends AbstractEntityImage { } final TextBlock stereo; - if (stereotype == null || stereotype.getLabel(false) == null + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null || portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) { stereo = null; } else { stereo = TextBlockUtils.withMargin( - Display.create(stereotype.getLabels(skinParam.useGuillemet())).create( + Display.create(stereotype.getLabels(skinParam.guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.CLASS_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam), 1, 0); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java index 6533d4281..b1d852de2 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java @@ -42,6 +42,7 @@ import java.util.HashSet; import java.util.Set; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.Url; @@ -62,7 +63,6 @@ import net.sourceforge.plantuml.graphic.SymbolContext; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.USymbol; -import net.sourceforge.plantuml.graphic.USymbolFolder; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.svek.AbstractEntityImage; @@ -140,9 +140,9 @@ public class EntityImageDescription extends AbstractEntityImage { if (stereotype != null && stereotype.getSprite(getSkinParam()) != null) { symbol = symbol.withStereoAlignment(HorizontalAlignment.RIGHT); stereo = stereotype.getSprite(getSkinParam()); - } else if (stereotype != null && stereotype.getLabel(false) != null + } else if (stereotype != null && stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) != null && portionShower.showPortion(EntityPortion.STEREOTYPE, entity)) { - stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().useGuillemet())).create( + stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())).create( new FontConfiguration(getSkinParam(), symbol.getFontParamStereotype(), stereotype), HorizontalAlignment.CENTER, getSkinParam()); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java index 416e26ad9..97255661b 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java @@ -41,6 +41,7 @@ import net.sourceforge.plantuml.AlignmentParam; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; @@ -83,12 +84,12 @@ public class EntityImageEmptyPackage extends AbstractEntityImage { HorizontalAlignment.CENTER, skinParam); this.url = entity.getUrl99(); - if (stereotype == null || stereotype.getLabel(false) == null + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null || portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) { stereoBlock = TextBlockUtils.empty(0, 0); } else { stereoBlock = TextBlockUtils.withMargin( - Display.create(stereotype.getLabels(skinParam.useGuillemet())).create( + Display.create(stereotype.getLabels(skinParam.guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.PACKAGE_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam), 1, 0); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java index 7892c5f7b..c989cbad3 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.svek.image; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.Url; @@ -95,9 +96,9 @@ public class EntityImageLollipopInterfaceEye2 extends AbstractEntityImage { this.ctx = new SymbolContext(backcolor, forecolor).withStroke(new UStroke(1.5)).withShadow( getSkinParam().shadowing(getEntity().getStereotype())); - if (stereotype != null && stereotype.getLabel(false) != null + if (stereotype != null && stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) != null && portionShower.showPortion(EntityPortion.STEREOTYPE, entity)) { - stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().useGuillemet())).create( + stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())).create( new FontConfiguration(getSkinParam(), symbol.getFontParamStereotype(), stereotype), HorizontalAlignment.CENTER, skinParam); } else { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java index a062be815..12832b657 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java @@ -40,12 +40,12 @@ import java.awt.geom.Line2D; import java.awt.geom.Point2D; import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; -import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.SkinParamBackcolored; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.Url; diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java index fcad8c49a..01736a1f3 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java @@ -38,12 +38,13 @@ package net.sourceforge.plantuml.svek.image; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineConfigurable; import net.sourceforge.plantuml.LineParam; -import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.SkinParamUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.creole.Stencil; @@ -92,11 +93,11 @@ public class EntityImageObject extends AbstractEntityImage implements Stencil { this.name = TextBlockUtils.withMargin( entity.getDisplay().create(new FontConfiguration(getSkinParam(), FontParam.OBJECT, stereotype), HorizontalAlignment.CENTER, skinParam), 2, 2); - if (stereotype == null || stereotype.getLabel(false) == null + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null || portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) { this.stereo = null; } else { - this.stereo = Display.create(stereotype.getLabels(skinParam.useGuillemet())).create( + this.stereo = Display.create(stereotype.getLabels(skinParam.guillemet())).create( new FontConfiguration(getSkinParam(), FontParam.OBJECT_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java index e8acfd3ee..e1a8bd092 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java @@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.SkinParamUtils; @@ -83,11 +84,11 @@ public class EntityImageUseCase extends AbstractEntityImage { final TextBlock tmp = new BodyEnhanced(entity.getDisplay(), FontParam.USECASE, skinParam, HorizontalAlignment.CENTER, stereotype, true, false, entity); - if (stereotype == null || stereotype.getLabel(false) == null + if (stereotype == null || stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null || portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) { this.desc = tmp; } else { - final TextBlock stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().useGuillemet())) + final TextBlock stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())) .create(new FontConfiguration(getSkinParam(), FontParam.USECASE_STEREOTYPE, stereotype), HorizontalAlignment.CENTER, skinParam); this.desc = TextBlockUtils.mergeTB(stereo, tmp, HorizontalAlignment.CENTER); diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index 38a0af761..ea1683d64 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -62,8 +62,8 @@ import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.code.Base64Coder; -import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.graphic.HtmlColorGradient; +import net.sourceforge.plantuml.tikz.TikzGraphics; import net.sourceforge.plantuml.ugraphic.ColorMapper; import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.USegment; @@ -89,6 +89,8 @@ public class SvgGraphics { // http://www.w3schools.com/svg/svg_feoffset.asp // http://www.adobe.com/svg/demos/samples.html + private static final String XLINK_HREF = "href"; + final private Document document; final private Element root; final private Element defs; @@ -326,7 +328,7 @@ public class SvgGraphics { pendingAction.add(0, (Element) document.createElement("a")); pendingAction.get(0).setAttribute("target", target); - pendingAction.get(0).setAttribute("xlink:href", url); + pendingAction.get(0).setAttribute(XLINK_HREF, url); pendingAction.get(0).setAttribute("xlink:type", "simple"); pendingAction.get(0).setAttribute("xlink:actuate", "onRequest"); pendingAction.get(0).setAttribute("xlink:show", "new"); @@ -476,16 +478,17 @@ public class SvgGraphics { elt.setTextContent(text); getG().appendChild(elt); - if (textDecoration != null && textDecoration.contains("underline")) { - final double delta = 2; - final Element elt2 = (Element) document.createElement("line"); - elt2.setAttribute("x1", format(x)); - elt2.setAttribute("y1", format(y + delta)); - elt2.setAttribute("x2", format(x + textLength)); - elt2.setAttribute("y2", format(y + delta)); - elt2.setAttribute("style", getStyleInternal(fill, "1.0", null)); - getG().appendChild(elt2); - } + // http://forum.plantuml.net/9158/hyperlink-without-underline + // if (textDecoration != null && textDecoration.contains("underline")) { + // final double delta = 2; + // final Element elt2 = (Element) document.createElement("line"); + // elt2.setAttribute("x1", format(x)); + // elt2.setAttribute("y1", format(y + delta)); + // elt2.setAttribute("x2", format(x + textLength)); + // elt2.setAttribute("y2", format(y + delta)); + // elt2.setAttribute("style", getStyleInternal(fill, "1.0", null)); + // getG().appendChild(elt2); + // } } ensureVisible(x, y); @@ -634,7 +637,7 @@ public class SvgGraphics { } else if (type == USegmentType.SEG_CLOSE) { // Nothing } else { - Log.println("unknown " + seg); + Log.println("unknown3 " + seg); } } @@ -696,7 +699,7 @@ public class SvgGraphics { } private String format(double x) { - return EpsGraphics.format(x * scale); + return TikzGraphics.format(x * scale); } private String formatBoolean(double x) { @@ -722,7 +725,7 @@ public class SvgGraphics { elt.setAttribute("x", format(x)); elt.setAttribute("y", format(y)); final String s = toBase64(image); - elt.setAttribute("xlink:href", "data:image/png;base64," + s); + elt.setAttribute(XLINK_HREF, "data:image/png;base64," + s); getG().appendChild(elt); } ensureVisible(x, y); diff --git a/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java b/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java index 602cf851e..972635f0a 100644 --- a/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java +++ b/src/net/sourceforge/plantuml/syntax/SyntaxChecker.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.syntax; -import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/src/net/sourceforge/plantuml/syntax/SyntaxResult.java b/src/net/sourceforge/plantuml/syntax/SyntaxResult.java index b63d6f6a0..473e8aafe 100644 --- a/src/net/sourceforge/plantuml/syntax/SyntaxResult.java +++ b/src/net/sourceforge/plantuml/syntax/SyntaxResult.java @@ -39,7 +39,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.TreeSet; import net.sourceforge.plantuml.FileFormatOption; diff --git a/src/net/sourceforge/plantuml/tikz/TikzGraphics.java b/src/net/sourceforge/plantuml/tikz/TikzGraphics.java index 874b8bdff..5598dfb6c 100644 --- a/src/net/sourceforge/plantuml/tikz/TikzGraphics.java +++ b/src/net/sourceforge/plantuml/tikz/TikzGraphics.java @@ -47,7 +47,6 @@ import java.util.List; import java.util.Map; import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.SignatureUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.ugraphic.UPath; @@ -271,8 +270,8 @@ public class TikzGraphics { return "(" + format(x) + "pt," + format(y) + "pt)"; } - private String format(double x) { - return EpsGraphics.format(x); + public static String format(double x) { + return EpsGraphics.formatSimple4(x); } private void out(OutputStream os, String s) throws IOException { @@ -495,7 +494,7 @@ public class TikzGraphics { } else if (type == USegmentType.SEG_CLOSE) { // Nothing } else { - Log.println("unknown " + seg); + Log.println("unknown4 " + seg); } } sb.append(";"); @@ -516,6 +515,20 @@ public class TikzGraphics { addCommand(sb); } + public void arc(double x, double y, int angleStart, int angleEnd, double radius) { + final StringBuilder sb = new StringBuilder(); + sb.append("\\draw["); + if (color != null) { + sb.append("color=" + getColorName(color) + ","); + } + if (fillcolor != null) { + sb.append("fill=" + getColorName(fillcolor) + ","); + } + sb.append("line width=" + thickness + "pt] " + couple(x, y) + " arc (" + angleStart + ":" + angleEnd + ":" + + format(radius) + "pt);"); + addCommand(sb); + } + public void drawSingleCharacter(double x, double y, char c) { final StringBuilder sb = new StringBuilder(); sb.append("\\node at "); diff --git a/src/net/sourceforge/plantuml/tim/ConditionalContext.java b/src/net/sourceforge/plantuml/tim/ConditionalContext.java new file mode 100644 index 000000000..f9135bc04 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/ConditionalContext.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 ConditionalContext { + + private boolean isTrue; + + private ConditionalContext(boolean isTrue) { + this.isTrue = isTrue; + } + + public static ConditionalContext fromValue(boolean isTrue) { + return new ConditionalContext(isTrue); + } + + public boolean conditionIsOkHere() { + return isTrue; + } + + public void nowInElse() { + this.isTrue = !isTrue; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/ConditionalContexts.java b/src/net/sourceforge/plantuml/tim/ConditionalContexts.java new file mode 100644 index 000000000..7471100a8 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/ConditionalContexts.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * 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 java.util.Deque; +import java.util.LinkedList; + +public class ConditionalContexts { + + private final Deque allIfs = new LinkedList(); + + public ConditionalContext peekConditionalContext() { + return allIfs.peekLast(); + } + + public void addConditionalContext(ConditionalContext fromValue) { + allIfs.addLast(fromValue); + } + + public ConditionalContext pollConditionalContext() { + return allIfs.pollLast(); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/Eater.java b/src/net/sourceforge/plantuml/tim/Eater.java new file mode 100644 index 000000000..b0e0fcde8 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/Eater.java @@ -0,0 +1,285 @@ +/* ======================================================================== + * 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 java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.tim.expression.Token; +import net.sourceforge.plantuml.tim.expression.TokenStack; +import net.sourceforge.plantuml.tim.expression.TokenType; + +public abstract class Eater { + + private int i = 0; + private final String s; + + public Eater(String s) { + this.s = s; + } + + public abstract void execute(TContext context, TMemory memory) throws EaterException; + + public int getCurrentPosition() { + return i; + } + + final protected String eatAllToEnd() throws EaterException { + final String result = s.substring(i); + i = s.length(); + return result; + } + + final protected TValue eatExpression(TContext context, TMemory memory) throws EaterException { + final TokenStack tokenStack = new TokenStack(); + addIntoTokenStack(tokenStack); + return tokenStack.getResult(context, memory); + } + + final protected void addIntoTokenStack(TokenStack tokenStack) throws EaterException { + while (true) { + final Token token = TokenType.eatOneToken(this); + // System.err.println("token=" + token); + if (token == null) { + return; + } + tokenStack.add(token); + } + } + + final public String eatAndGetQuotedString() throws EaterException { + final char separator = peekChar(); + if (TLineType.isQuote(separator) == false) { + throw new EaterException("quote10"); + } + checkAndEatChar(separator); + final StringBuilder value = new StringBuilder(); + addUpTo(separator, value); + checkAndEatChar(separator); + return value.toString(); + } + + final protected String eatAndGetOptionalQuotedString() throws EaterException { + final char quote = peekChar(); + if (TLineType.isQuote(quote)) { + return eatAndGetQuotedString(); + } + final StringBuilder value = new StringBuilder(); + addUpTo(',', ')', value); + return value.toString(); + } + + final public String eatAndGetNumber() throws EaterException { + final StringBuilder result = new StringBuilder(); + while (true) { + final char ch = peekChar(); + if (ch == 0 || TLineType.isLatinDigit(ch) == false) { + return result.toString(); + } + result.append(eatOneChar()); + } + } + + final public String eatAndGetSpaces() throws EaterException { + final StringBuilder result = new StringBuilder(); + while (true) { + final char ch = peekChar(); + if (ch == 0 || TLineType.isSpaceChar(ch) == false) { + return result.toString(); + } + result.append(eatOneChar()); + } + } + + final protected String eatAntGetVarname() throws EaterException { + final StringBuilder varname = new StringBuilder("" + eatOneChar()); + if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) { + throw new EaterException("a002"); + } + addUpToLastLetterOrUnderscoreOrDigit(varname); + return varname.toString(); + } + + final protected String eatAntGetFunctionName() throws EaterException { + final StringBuilder varname = new StringBuilder("" + eatOneChar()); + if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) { + throw new EaterException("a003"); + } + addUpToLastLetterOrUnderscoreOrDigit(varname); + return varname.toString(); + } + + final public void skipSpaces() { + while (i < s.length() && Character.isSpaceChar(s.charAt(i))) { + i++; + } + } + + final protected void skipUntilChar(char ch) { + while (i < s.length() && s.charAt(i) != ch) { + i++; + } + } + + final public char peekChar() { + if (i >= s.length()) { + return 0; + } + return s.charAt(i); + } + + final public char peekCharN2() { + if (i + 1 >= s.length()) { + return 0; + } + return s.charAt(i + 1); + } + + final protected boolean hasNextChar() { + return i < s.length(); + } + + final public char eatOneChar() { + final char ch = s.charAt(i); + i++; + return ch; + } + + final protected void checkAndEatChar(char ch) throws EaterException { + if (i >= s.length() || s.charAt(i) != ch) { + throw new EaterException("a001"); + } + i++; + } + + final protected void optionallyEatChar(char ch) throws EaterException { + if (i >= s.length() || s.charAt(i) != ch) { + return; + } + assert s.charAt(i) == ch; + i++; + } + + final protected void checkAndEatChar(String s) throws EaterException { + for (int j = 0; j < s.length(); j++) { + checkAndEatChar(s.charAt(j)); + } + } + + final protected void addUpToLastLetterOrUnderscoreOrDigit(StringBuilder sb) { + while (i < s.length()) { + final char ch = s.charAt(i); + if (TLineType.isLetterOrUnderscoreOrDigit(ch) == false) { + return; + } + i++; + sb.append(ch); + } + } + + final protected void addUpTo(char separator, StringBuilder sb) { + while (i < s.length()) { + final char ch = peekChar(); + if (ch == separator) { + return; + } + i++; + sb.append(ch); + } + } + + final protected void addUpTo(char separator1, char separator2, StringBuilder sb) { + while (i < s.length()) { + final char ch = peekChar(); + if (ch == separator1 || ch == separator2) { + return; + } + i++; + sb.append(ch); + } + } + + final protected TFunctionImpl eatDeclareFunction(TContext context, TMemory memory, boolean unquoted, + LineLocation location) throws EaterException { + final List args = new ArrayList(); + final String functionName = eatAntGetFunctionName(); + skipSpaces(); + checkAndEatChar('('); + while (true) { + skipSpaces(); + char ch = peekChar(); + if (TLineType.isLetterOrUnderscoreOrDollar(ch)) { + final String varname = eatAntGetVarname(); + skipSpaces(); + final TValue defValue; + if (peekChar() == '=') { + eatOneChar(); + final TokenStack def = TokenStack.eatUntilCloseParenthesisOrComma(this); + def.guessFunctions(); + defValue = def.getResult(context, memory); + // System.err.println("result=" + defValue); + } else { + defValue = null; + } + args.add(new TFunctionArgument(varname, defValue)); + } else if (ch == ',') { + checkAndEatChar(','); + } else if (ch == ')') { + checkAndEatChar(")"); + break; + } else { + throw new EaterException("Error in function definition"); + } + } + skipSpaces(); + return new TFunctionImpl(functionName, args, unquoted); + } + + final protected TFunctionImpl eatDeclareFunctionWithOptionalReturn(TContext context, TMemory memory, + boolean unquoted, LineLocation location) throws EaterException { + final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location); + if (peekChar() == 'r') { + checkAndEatChar("return"); + skipSpaces(); + final String line = "!return " + eatAllToEnd(); + result.addBody(new StringLocated(line, location)); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterAffectation.java b/src/net/sourceforge/plantuml/tim/EaterAffectation.java new file mode 100644 index 000000000..d0dacacff --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterAffectation.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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.tim.expression.TValue; + +public class EaterAffectation extends Eater { + + public EaterAffectation(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!"); + skipSpaces(); + final String varname = eatAntGetVarname(); + skipSpaces(); + checkAndEatChar('='); + skipSpaces(); + final TValue value = eatExpression(context, memory); + memory.put(varname, new TVariable(value)); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java b/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java new file mode 100644 index 000000000..24effb6e5 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterAffectationDefine.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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.tim.expression.TValue; + +public class EaterAffectationDefine extends Eater { + + public EaterAffectationDefine(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!define"); + skipSpaces(); + final String varname = eatAntGetVarname(); + skipSpaces(); + final TValue value = TValue.fromString(eatAllToEnd()); + memory.put(varname, new TVariable(value)); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java b/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java new file mode 100644 index 000000000..4064d6fb5 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterDeclareFunction.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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.LineLocation; +import net.sourceforge.plantuml.StringLocated; + +public class EaterDeclareFunction extends Eater { + + private TFunctionImpl function; + private final LineLocation location; + + public EaterDeclareFunction(StringLocated s) { + super(s.getStringTrimmed()); + this.location = s.getLocation(); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!"); + final boolean unquoted; + if (peekChar() == 'u') { + checkAndEatChar("unquoted function"); + unquoted = true; + } else { + checkAndEatChar("function"); + unquoted = false; + } + skipSpaces(); + function = eatDeclareFunctionWithOptionalReturn(context, memory, unquoted, location); + } + + public TFunctionImpl getFunction() { + return function; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterException.java b/src/net/sourceforge/plantuml/tim/EaterException.java new file mode 100644 index 000000000..f3d04567c --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterException.java @@ -0,0 +1,49 @@ +/* ======================================================================== + * 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 EaterException extends Exception { + + private final String message; + + public EaterException(String message) { + this.message = message; + } + + public final String getMessage() { + return message; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java new file mode 100644 index 000000000..d97e68245 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java @@ -0,0 +1,108 @@ +/* ======================================================================== + * 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 java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.tim.expression.TokenStack; + +public class EaterFunctionCall extends Eater { + + private final List values = new ArrayList(); + private final boolean isLegacyDefine; + private final boolean unquoted; + + public EaterFunctionCall(String s, boolean isLegacyDefine, boolean unquoted) { + super(s); + this.isLegacyDefine = isLegacyDefine; + this.unquoted = unquoted; + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + skipUntilChar('('); + checkAndEatChar('('); + skipSpaces(); + if (peekChar() == ')') { + return; + } + while (true) { + skipSpaces(); + if (isLegacyDefine || unquoted) { + final TValue result = TValue.fromString(eatAndGetOptionalQuotedString()); + values.add(result); + } else { + final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace(); + tokens.guessFunctions(); + final TValue result = tokens.getResult(context, memory); + values.add(result); + } + skipSpaces(); + final char ch = eatOneChar(); + if (ch == ',') { + continue; + } + if (ch == ')') { + break; + } + throw new EaterException("call001"); + } + } + + 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() { + return Collections.unmodifiableList(values); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterIf.java b/src/net/sourceforge/plantuml/tim/EaterIf.java new file mode 100644 index 000000000..4e50bc92a --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterIf.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; + +import net.sourceforge.plantuml.tim.expression.TValue; + +public class EaterIf extends Eater { + + private boolean booleanValue; + + public EaterIf(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!if"); + 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/EaterIfdef.java b/src/net/sourceforge/plantuml/tim/EaterIfdef.java new file mode 100644 index 000000000..05fba5bfd --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterIfdef.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 EaterIfdef extends Eater { + + private String varname; + + public EaterIfdef(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!ifdef"); + skipSpaces(); + varname = eatAntGetVarname(); + } + + public boolean isTrue(TContext context, TMemory memory) { + final TVariable currentValue = memory.getVariable(varname); + return currentValue != null || context.doesFunctionExist(varname); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterIfndef.java b/src/net/sourceforge/plantuml/tim/EaterIfndef.java new file mode 100644 index 000000000..0c5b8e472 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterIfndef.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 EaterIfndef extends Eater { + + private String varname; + + public EaterIfndef(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!ifndef"); + skipSpaces(); + varname = eatAntGetVarname(); + } + + public boolean isTrue(TContext context, TMemory memory) { + final TVariable currentValue = memory.getVariable(varname); + return currentValue == null && context.doesFunctionExist(varname) == false; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterImport.java b/src/net/sourceforge/plantuml/tim/EaterImport.java new file mode 100644 index 000000000..21f098777 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterImport.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 EaterImport extends Eater { + + private String location; + + public EaterImport(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!import"); + skipSpaces(); + this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd()); + + } + + public final String getLocation() { + return location; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterInclude.java b/src/net/sourceforge/plantuml/tim/EaterInclude.java new file mode 100644 index 000000000..59a4bae46 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterInclude.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 EaterInclude extends Eater { + + private String location; + + public EaterInclude(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!include"); + if (peekChar() == 'u') { + checkAndEatChar("url"); + } + skipSpaces(); + this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd()); + + } + + public final String getLocation() { + return location; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java b/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java new file mode 100644 index 000000000..edd71c9c1 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterLegacyDefine.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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.LineLocation; +import net.sourceforge.plantuml.StringLocated; + +public class EaterLegacyDefine extends Eater { + + private TFunctionImpl function; + private final LineLocation location; + + public EaterLegacyDefine(StringLocated s) { + super(s.getStringTrimmed()); + this.location = s.getLocation(); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!define"); + skipSpaces(); + function = eatDeclareFunction(context, memory, true, location); + final String def = this.eatAllToEnd(); + function.setFunctionType(TFunctionType.LEGACY_DEFINE); + function.setLegacyDefinition(def); + } + + public TFunction getFunction() { + return function; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java b/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java new file mode 100644 index 000000000..467c43338 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterLegacyDefineLong.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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.LineLocation; +import net.sourceforge.plantuml.StringLocated; + +public class EaterLegacyDefineLong extends Eater { + + private TFunctionImpl function; + private final LineLocation location; + + public EaterLegacyDefineLong(StringLocated s) { + super(s.getStringTrimmed()); + this.location = s.getLocation(); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!definelong"); + skipSpaces(); + function = eatDeclareFunction(context, memory, true, location); + function.setFunctionType(TFunctionType.LEGACY_DEFINELONG); + } + + public TFunctionImpl getFunction() { + return function; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/EaterReturn.java b/src/net/sourceforge/plantuml/tim/EaterReturn.java new file mode 100644 index 000000000..48d55e61e --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/EaterReturn.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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.tim.expression.TValue; + +public class EaterReturn extends Eater { + + private TValue value; + + public EaterReturn(String s) { + super(s); + } + + @Override + public void execute(TContext context, TMemory memory) throws EaterException { + checkAndEatChar("!return"); + skipSpaces(); + this.value = eatExpression(context, memory); + } + + public final TValue getValue2() { + return value; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java new file mode 100644 index 000000000..b2ebcae00 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -0,0 +1,517 @@ +/* ======================================================================== + * 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 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.List; +import java.util.Map; + +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; +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.preproc2.PreprocessorInclude; +import net.sourceforge.plantuml.tim.expression.Knowledge; +import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.tim.stdlib.Strlen; + +public class TContext { + + private final ArrayList result = new ArrayList(); + private final Map functions2 = new HashMap(); + private final Trie functions3 = new Trie(); + private final ImportedFiles importedFiles; + + private TFunctionImpl pendingFunction; + + public TContext(ImportedFiles importedFiles) { + this.importedFiles = importedFiles; + this.addStandardFunctions(); + } + + public Knowledge asKnowledge(final TMemory memory) { + return new Knowledge() { + + public TVariable getVariable(String name) { + return memory.getVariable(name); + } + + public TFunction getFunction(TFunctionSignature name) { + return getFunctionSmart(name); + } + }; + } + + private TFunction getFunctionSmart(TFunctionSignature searched) { + final TFunction func = functions2.get(searched); + if (func != null) { + return func; + } + for (TFunction candidate : functions2.values()) { + if (candidate.getSignature().sameNameAs(searched) == false) { + continue; + } + if (candidate.canCover(searched.getNbArg())) { + return candidate; + } + } + return null; + } + + public CommandExecutionResult executeOneLine(TMemory memory, TLineType type, StringLocated s, TFunctionType fromType) { + if (this.getPendingFunction() != null) { + if (type == TLineType.END_FUNCTION) { + this.executeEndfunction(); + } else { + this.getPendingFunction().addBody(s); + } + return CommandExecutionResult.ok(); + } + assert type == TLineType.getFromLine(s.getString()); + try { + + 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()); + } + + } + + private CommandExecutionResult addPlain(TMemory memory, StringLocated s) throws EaterException { + StringLocated tmp = applyFunctionsAndVariables(memory, s); + if (tmp != null) { + if (pendingAdd != null) { + tmp = new StringLocated(pendingAdd + tmp.getString(), tmp.getLocation()); + pendingAdd = null; + } + result.add(tmp); + } + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult 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 { + new EaterAffectation(s).execute(this, memory); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult 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 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 { + 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 { + final ConditionalContext poll = memory.peekConditionalContext(); + if (poll == null) { + return CommandExecutionResult.error("No if related to this else"); + } + poll.nowInElse(); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeEndif(TMemory memory, String s) throws EaterException { + final ConditionalContext poll = memory.pollConditionalContext(); + if (poll == null) { + return CommandExecutionResult.error("No if related to this endif"); + } + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult 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"); + } + if (declareFunction.getFunction().hasBody()) { + addFunction(declareFunction.getFunction()); + } else { + this.pendingFunction = declareFunction.getFunction(); + } + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult 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"); + } + this.functions2.put(function.getSignature(), function); + this.functions3.add(function.getSignature().getFunctionName() + "("); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult 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"); + } + this.pendingFunction = legacyDefineLong.getFunction(); + return CommandExecutionResult.ok(); + } + + private StringLocated applyFunctionsAndVariables(TMemory memory, StringLocated located) throws EaterException { + if (memory.isEmpty() && functions2.size() == 0) { + return located; + } + final String s = located.getString(); + final String result = applyFunctionsAndVariables(memory, s); + if (result == null) { + return null; + } + return new StringLocated(result, located.getLocation()); + } + + private String pendingAdd = null; + + public String applyFunctionsAndVariables(TMemory memory, String s) throws EaterException { + // https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm + // https://stackoverflow.com/questions/1326682/java-replacing-multiple-different-substring-in-a-string-at-once-or-in-the-most + // https://en.wikipedia.org/wiki/String-searching_algorithm + // https://www.quora.com/What-is-the-most-efficient-algorithm-to-replace-all-occurrences-of-a-pattern-P-in-a-string-with-a-pattern-P + // https://en.wikipedia.org/wiki/Trie + if (memory.isEmpty() && functions2.size() == 0) { + return s; + } + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + final String presentFunction = getFunctionNameAt(s, i); + if (presentFunction != null) { + final String sub = s.substring(i); + final EaterFunctionCall call = new EaterFunctionCall(sub, isLegacyDefine(presentFunction), + isUnquoted(presentFunction)); + call.execute(this, memory); + final TFunction function = getFunctionSmart(new TFunctionSignature(presentFunction, call.getValues2() + .size())); + if (function == null) { + throw new EaterException("apply4522"); + } + if (function.getFunctionType() == TFunctionType.VOID) { + function.executeVoid(this, sub, memory); + return null; + } + if (function.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) { + this.pendingAdd = s.substring(0, i); + function.executeVoid(this, sub, memory); + return null; + } + assert function.getFunctionType() == TFunctionType.RETURN + || function.getFunctionType() == TFunctionType.LEGACY_DEFINE; + final TValue functionReturn = function.executeReturn(this, memory, call.getValues2()); + result.append(functionReturn.toString()); + i += call.getCurrentPosition() - 1; + continue; + } + final String presentVariable = getVarnameAt(memory, s, i); + if (presentVariable != null) { + result.append(memory.getVariable(presentVariable).getValue2().toString()); + i += presentVariable.length() - 1; + if (i + 2 < s.length() && s.charAt(i + 1) == '#' && s.charAt(i + 2) == '#') { + i += 2; + } + continue; + } + result.append(c); + } + return result.toString(); + } + + private CommandExecutionResult executeImport(TMemory memory, StringLocated s) throws EaterException { + final EaterImport _import = new EaterImport(s.getStringTrimmed()); + _import.execute(this, memory); + + try { + final File file = FileSystem.getInstance().getFile( + applyFunctionsAndVariables(memory, _import.getLocation())); + if (file.exists() && file.isDirectory() == false) { + importedFiles.add(file); + return CommandExecutionResult.ok(); + } + } catch (IOException e) { + e.printStackTrace(); + return CommandExecutionResult.error("Cannot import " + e.getMessage()); + } + + return CommandExecutionResult.error("Cannot import"); + } + + private CommandExecutionResult executeInclude(TMemory memory, StringLocated s) throws EaterException { + final EaterInclude include = new EaterInclude(s.getStringTrimmed()); + include.execute(this, memory); + String location = include.getLocation(); + final int idx = location.lastIndexOf('!'); + String suf = null; + if (idx != -1) { + suf = location.substring(idx + 1); + location = location.substring(0, idx); + } + + final String charset = null; + + ReadLine reader2 = null; + try { + if (location.startsWith("http://") || location.startsWith("https://")) { + final URL url = new URL(location); + reader2 = PreprocessorInclude.getReaderIncludeUrl(url, s, suf, charset); + + } + if (location.startsWith("<") && location.endsWith(">")) { + reader2 = PreprocessorInclude.getReaderStdlibInclude(s, location.substring(1, location.length() - 1)); + } 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 (reader2 != null) { + do { + final StringLocated sl = reader2.readLine(); + if (sl == null) { + return CommandExecutionResult.ok(); + } + 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); + } + + 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); + } + + public boolean isLegacyDefine(String functionName) { + for (Map.Entry ent : functions2.entrySet()) { + if (ent.getKey().getFunctionName().equals(functionName) && ent.getValue().getFunctionType().isLegacy()) { + return true; + } + } + return false; + } + + public boolean isUnquoted(String functionName) { + for (Map.Entry ent : functions2.entrySet()) { + if (ent.getKey().getFunctionName().equals(functionName) && ent.getValue().isUnquoted()) { + return true; + } + } + return false; + } + + public boolean doesFunctionExist(String functionName) { + for (Map.Entry ent : functions2.entrySet()) { + if (ent.getKey().getFunctionName().equals(functionName)) { + return true; + } + } + return false; + } + + private static String getVarnameAt(TMemory memory, String s, int pos) { + final String varname = memory.variablesNames3().getLonguestMatchStartingIn(s.substring(pos)); + if (varname.length() == 0) { + return null; + } + if (pos + varname.length() == s.length() + || Character.isLetterOrDigit(s.charAt(pos + varname.length())) == false) { + return varname; + } + 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) { + return null; + } + 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); + } + + public List getResultWithError(StringLocated error) { + result.add(error); + return Collections.unmodifiableList(result); + } + + public final TFunctionImpl getPendingFunction() { + return pendingFunction; + } + + private void addFunction(TFunction func) { + this.functions2.put(func.getSignature(), func); + this.functions3.add(func.getSignature().getFunctionName() + "("); + } + + private void addStandardFunctions() { + addFunction(new Strlen()); + } + + public void executeEndfunction() { + addFunction(pendingFunction); + pendingFunction = null; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TFunction.java b/src/net/sourceforge/plantuml/tim/TFunction.java new file mode 100644 index 000000000..beb645cce --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TFunction.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 java.util.List; + +import net.sourceforge.plantuml.tim.expression.TValue; + +public interface TFunction { + + public TFunctionSignature getSignature(); + + public boolean canCover(int nbArg); + + public TFunctionType getFunctionType(); + + public void executeVoid(TContext context, String s, TMemory memory) throws EaterException; + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException; + + public boolean isUnquoted(); + +} diff --git a/src/net/sourceforge/plantuml/tim/TFunctionArgument.java b/src/net/sourceforge/plantuml/tim/TFunctionArgument.java new file mode 100644 index 000000000..82baac100 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TFunctionArgument.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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.tim.expression.TValue; + +public class TFunctionArgument { + + private final String name; + private final TValue def; + + public TFunctionArgument(String name, TValue def) { + this.name = name; + this.def = def; + } + + public final String getName() { + return name; + } + + @Override + public String toString() { + return "ARG:" + name; + } + + public final TValue getOptionalDefaultValue() { + return def; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java new file mode 100644 index 000000000..74b8be87d --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java @@ -0,0 +1,174 @@ +/* ======================================================================== + * 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 java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class TFunctionImpl implements TFunction { + + private final TFunctionSignature signature; + private final List args; + private final List body = new ArrayList(); + private final boolean unquoted; + private TFunctionType functionType = TFunctionType.VOID; + private String legacyDefinition; + + public TFunctionImpl(String functionName, List args, boolean unquoted) { + this.signature = new TFunctionSignature(functionName, args.size()); + this.args = args; + this.unquoted = unquoted; + } + + public boolean canCover(int nbArg) { + if (nbArg > args.size()) { + return false; + } + for (int i = nbArg; i < args.size(); i++) { + if (args.get(i).getOptionalDefaultValue() == null) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "FUNCTION " + signature + " " + args; + } + + public void addBody(StringLocated s) { + body.add(s); + if (TLineType.getFromLine(s.getString()) == TLineType.RETURN) { + this.functionType = TFunctionType.RETURN; + } + } + + public void executeVoid(TContext context, String s, TMemory memory) throws EaterException { + if (functionType != TFunctionType.VOID && functionType != TFunctionType.LEGACY_DEFINELONG) { + throw new IllegalStateException(); + } + 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()); + } + } + + } + + private TMemory getNewMemory(TMemory memory, List values) { + final TMemory copy = memory.forkFromGlobal(); + 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)); + } + return copy; + } + + public TValue executeReturn(TContext context, TMemory memory, List args) throws EaterException { + if (functionType == TFunctionType.LEGACY_DEFINE) { + return executeReturnLegacyDefine(context, memory, args); + } + if (functionType != TFunctionType.RETURN) { + throw new IllegalStateException(); + } + final TMemory copy = getNewMemory(memory, args); + + for (StringLocated sl : body) { + final TLineType lineType = TLineType.getFromLine(sl.getString()); + final ConditionalContext conditionalContext = copy.peekConditionalContext(); + if ((conditionalContext == null || conditionalContext.conditionIsOkHere()) && lineType == TLineType.RETURN) { + // System.err.println("s2=" + sl.getString()); + final EaterReturn eaterReturn = new EaterReturn(sl.getString()); + eaterReturn.execute(context, copy); + // 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()); + } + } + throw new EaterException("no return"); + // return TValue.fromString("(NONE)"); + } + + private TValue executeReturnLegacyDefine(TContext context, TMemory memory, List args) throws EaterException { + if (legacyDefinition == null) { + throw new IllegalStateException(); + } + final TMemory copy = getNewMemory(memory, args); + final String tmp = context.applyFunctionsAndVariables(copy, legacyDefinition); + return TValue.fromString(tmp); + // eaterReturn.execute(context, copy); + // // System.err.println("s3=" + eaterReturn.getValue2()); + // return eaterReturn.getValue2(); + } + + public final TFunctionType getFunctionType() { + return functionType; + } + + public final TFunctionSignature getSignature() { + return signature; + } + + public void setFunctionType(TFunctionType type) { + this.functionType = type; + } + + public void setLegacyDefinition(String legacyDefinition) { + this.legacyDefinition = legacyDefinition; + } + + public boolean isUnquoted() { + return unquoted; + } + + public boolean hasBody() { + return body.size() > 0; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TFunctionSignature.java b/src/net/sourceforge/plantuml/tim/TFunctionSignature.java new file mode 100644 index 000000000..c0b9ad768 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TFunctionSignature.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * 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 TFunctionSignature { + + private final String functionName; + private final int nbArg; + + public TFunctionSignature(String functionName, int nbArg) { + if (functionName == null) { + throw new IllegalArgumentException(); + } + this.functionName = functionName; + this.nbArg = nbArg; + } + + public boolean sameNameAs(TFunctionSignature other) { + return getFunctionName().equals(other.getFunctionName()); + } + + @Override + public String toString() { + return functionName + "/" + nbArg; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + functionName.hashCode(); + result = prime * result + nbArg; + return result; + } + + @Override + public boolean equals(Object obj) { + final TFunctionSignature other = (TFunctionSignature) obj; + return functionName.equals(other.functionName) && nbArg == other.nbArg; + } + + public final String getFunctionName() { + return functionName; + } + + public final int getNbArg() { + return nbArg; + } +} diff --git a/src/net/sourceforge/plantuml/tim/TFunctionType.java b/src/net/sourceforge/plantuml/tim/TFunctionType.java new file mode 100644 index 000000000..e94bb77be --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TFunctionType.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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 enum TFunctionType { + + VOID, RETURN, LEGACY_DEFINE, LEGACY_DEFINELONG; + + public boolean isLegacy() { + return this == LEGACY_DEFINE || this == LEGACY_DEFINELONG; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TLineType.java b/src/net/sourceforge/plantuml/tim/TLineType.java new file mode 100644 index 000000000..bdf391ffb --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TLineType.java @@ -0,0 +1,119 @@ +/* ======================================================================== + * 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 enum TLineType { + + PLAIN, AFFECTATION_DEFINE, AFFECTATION, IF, IFDEF, IFNDEF, ELSE, ENDIF, DECLARE_FUNCTION, END_FUNCTION, RETURN, LEGACY_DEFINE, LEGACY_DEFINELONG, INCLUDE, IMPORT; + + public static TLineType getFromLine(String s) { + if (s.matches("^!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*")) { + return LEGACY_DEFINE; + } + if (s.matches("^!definelong\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { + return LEGACY_DEFINELONG; + } + if (s.matches("^!define\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { + return AFFECTATION_DEFINE; + } + if (s.matches("^!\\s*\\$?[\\p{L}_][\\p{L}_0-9]*\\s*=.*")) { + return AFFECTATION; + } + if (s.matches("^!ifdef\\s+.*")) { + return IFDEF; + } + if (s.matches("^!ifndef\\s+.*")) { + return IFNDEF; + } + if (s.matches("^!if\\s+.*")) { + return IF; + } + if (s.matches("^!(unquoted\\s)?function\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*")) { + return DECLARE_FUNCTION; + } + if (s.matches("^!else\\b.*")) { + return ELSE; + } + if (s.matches("^!endif\\b.*")) { + return ENDIF; + } + if (s.matches("^!(endfunction|enddefinelong)\\b.*")) { + return END_FUNCTION; + } + if (s.matches("^!return\\b.*")) { + return RETURN; + } + if (s.matches("^!(include|includeurl)\\b.*")) { + return INCLUDE; + } + if (s.matches("^!(import)\\b.*")) { + return IMPORT; + } + return PLAIN; + } + + public static boolean isQuote(char ch) { + return ch == '\"' || ch == '\''; + } + + public static boolean isLetterOrUnderscoreOrDigit(char ch) { + return isLetterOrUnderscore(ch) || isLatinDigit(ch); + } + + public static boolean isLetterOrUnderscore(char ch) { + return isLetter(ch) || ch == '_'; + } + + public static boolean isLetterOrUnderscoreOrDollar(char ch) { + return isLetterOrUnderscore(ch) || ch == '$'; + } + + public static boolean isLetterOrDigit(char ch) { + return isLetter(ch) || isLatinDigit(ch); + } + + public static boolean isLetter(char ch) { + return Character.isLetter(ch); + } + + public static boolean isSpaceChar(char ch) { + return Character.isSpaceChar(ch); + } + + public static boolean isLatinDigit(char ch) { + return ch >= '0' && ch <= '9'; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TMemory.java b/src/net/sourceforge/plantuml/tim/TMemory.java new file mode 100644 index 000000000..3c9e50a83 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TMemory.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 java.util.Set; + +public interface TMemory { + + public TVariable getVariable(String varname); + + public void put(String varname, TVariable value); + + public boolean isEmpty(); + + public Set variablesNames(); + + public Trie variablesNames3(); + + public TMemory forkFromGlobal(); + + public ConditionalContext peekConditionalContext(); + + public void addConditionalContext(ConditionalContext context); + + public ConditionalContext pollConditionalContext(); +} diff --git a/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java b/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java new file mode 100644 index 000000000..e1d8ed0af --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TMemoryGlobal.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class TMemoryGlobal extends ConditionalContexts implements TMemory { + + private final Map globalVariables = new HashMap(); + private final Trie variables = new Trie(); + + public TVariable getVariable(String varname) { + return this.globalVariables.get(varname); + } + + public void put(String varname, TVariable value) { + this.globalVariables.put(varname, value); + this.variables.add(varname); + } + + public boolean isEmpty() { + return globalVariables.isEmpty(); + } + + public Set variablesNames() { + return Collections.unmodifiableSet(globalVariables.keySet()); + } + + public Trie variablesNames3() { + return variables; + } + + public TMemory forkFromGlobal() { + return new TMemoryLocal(this); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TMemoryLocal.java b/src/net/sourceforge/plantuml/tim/TMemoryLocal.java new file mode 100644 index 000000000..441919d7f --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TMemoryLocal.java @@ -0,0 +1,96 @@ +/* ======================================================================== + * 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 java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class TMemoryLocal extends ConditionalContexts implements TMemory { + + private final TMemoryGlobal global; + private final Map localVariables = new HashMap(); + private Trie variables; + + public TMemoryLocal(TMemoryGlobal global) { + this.global = global; + } + + private void initTrie() { + for (String name : global.variablesNames()) { + variables.add(name); + } + } + + public TVariable getVariable(String varname) { + final TVariable result = localVariables.get(varname); + if (result != null) { + return result; + } + return global.getVariable(varname); + } + + public Trie variablesNames3() { + if (variables == null) { + return global.variablesNames3(); + } + return variables; + } + + public void put(String varname, TVariable value) { + this.localVariables.put(varname, value); + if (this.variables == null) { + this.variables = new Trie(); + initTrie(); + } + this.variables.add(varname); + } + + public boolean isEmpty() { + return global.isEmpty() && localVariables.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); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TMode.java b/src/net/sourceforge/plantuml/tim/TMode.java new file mode 100644 index 000000000..711a05e50 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TMode.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 TMode { + +} diff --git a/src/net/sourceforge/plantuml/tim/TVariable.java b/src/net/sourceforge/plantuml/tim/TVariable.java new file mode 100644 index 000000000..c92f23e62 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TVariable.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; + +import net.sourceforge.plantuml.tim.expression.TValue; + +public class TVariable { + + private final TValue value; + + public TVariable(TValue value) { + if (value == null) { + throw new IllegalArgumentException(); + } + this.value = value; + } + + @Override + public String toString() { + return super.toString() + " " + value.toString(); + } + + public TValue getValue2() { + return value; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TimLoader.java b/src/net/sourceforge/plantuml/tim/TimLoader.java new file mode 100644 index 000000000..348b1f11f --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/TimLoader.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.preproc.ImportedFiles; + +public class TimLoader { + + private final TContext context; + private final TMemory global = new TMemoryGlobal(); + + public TimLoader(ImportedFiles importedFiles) { + this.context = new TContext(importedFiles); + } + + public List load(List input) { + for (StringLocated s : input) { + if (s.getPreprocessorError() != null) { + return new ArrayList(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())); + } + } + return context.getResult(); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/Trie.java b/src/net/sourceforge/plantuml/tim/Trie.java new file mode 100644 index 000000000..eb060fd2c --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/Trie.java @@ -0,0 +1,105 @@ +/* ======================================================================== + * 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 java.util.HashMap; +import java.util.Map; + +public class Trie { + + private final Map brothers = new HashMap(); + + private boolean terminalWord = false; + + public void add(String s) { + add(this, s); + } + + private static void add(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; + } + } + + private Trie getOrCreate(Character added) { + Trie result = brothers.get(added); + if (result == null) { + result = new Trie(); + brothers.put(added, result); + } + return result; + } + + public String getLonguestMatchStartingIn(String s) { + return getLonguestMatchStartingIn(this, s); + } + + private static String getLonguestMatchStartingIn(Trie current, String s) { + final StringBuilder result = new StringBuilder(); + while (current != null) { + if (s.length() == 0) { + if (current.terminalWord) { + return result.toString(); + } else { + return ""; + } + } + final Trie child = current.brothers.get(s.charAt(0)); + if (child == null) { + if (current.terminalWord) { + return result.toString(); + } else { + return ""; + } + } + result.append(s.charAt(0)); + current = child; + s = s.substring(1); + } + return ""; + + } + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/Expression.java b/src/net/sourceforge/plantuml/tim/expression/Expression.java new file mode 100644 index 000000000..ca65b9fd8 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/Expression.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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.expression; + + +public class Expression { + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/Knowledge.java b/src/net/sourceforge/plantuml/tim/expression/Knowledge.java new file mode 100644 index 000000000..78815b7df --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/Knowledge.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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.expression; + +import net.sourceforge.plantuml.tim.TFunction; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TVariable; + +public interface Knowledge { + + public TVariable getVariable(String name); + + public TFunction getFunction(TFunctionSignature signature); + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java b/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java new file mode 100644 index 000000000..4ddb5a3dc --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java @@ -0,0 +1,111 @@ +/* ======================================================================== + * 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.expression; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +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; + +public class ReversePolishInterpretor { + + private final TValue result; + private boolean trace = false; + + public ReversePolishInterpretor(TokenStack queue, Knowledge knowledge, TMemory memory, TContext context) + throws EaterException { + + final Deque stack = new ArrayDeque(); + if (trace) + System.err.println("ReversePolishInterpretor::queue=" + queue); + for (TokenIterator it = queue.tokenIterator(); it.hasMoreTokens();) { + final Token token = it.nextToken(); + if (trace) + System.err.println("rpn " + token); + if (token.getTokenType() == TokenType.NUMBER) { + stack.addFirst(TValue.fromNumber(token)); + } else if (token.getTokenType() == TokenType.QUOTED_STRING) { + stack.addFirst(TValue.fromString(token)); + } else if (token.getTokenType() == TokenType.OPERATOR) { + final TValue v2 = stack.removeFirst(); + final TValue v1 = stack.removeFirst(); + final TokenOperator op = token.getTokenOperator(); + if (op == null) { + throw new EaterException("bad op"); + } + final TValue tmp = op.operate(v1, v2); + stack.addFirst(tmp); + } else if (token.getTokenType() == TokenType.OPEN_PAREN_FUNC) { + final int nb2 = Integer.parseInt(token.getSurface()); + final Token token2 = it.nextToken(); + if (token2.getTokenType() != TokenType.FUNCTION_NAME) { + throw new EaterException("rpn43"); + } + if (trace) + System.err.println("token2=" + token2); + final TFunction function = knowledge.getFunction(new TFunctionSignature(token2.getSurface(), nb2)); + if (trace) + System.err.println("function=" + function); + final int nb = function.getSignature().getNbArg(); + if (nb != nb2) { + throw new EaterException("rpn4"); + } + final List args = new ArrayList(); + for (int i = 0; i < nb; i++) { + args.add(0, stack.removeFirst()); + } + if (trace) + System.err.println("args=" + args); + final TValue r = function.executeReturn(context, memory, args); + if (trace) + System.err.println("r=" + r); + stack.addFirst(r); + } else { + throw new EaterException("rpn41"); + } + } + result = stack.removeFirst(); + } + + public final TValue getResult() { + return result; + } +} diff --git a/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java b/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java new file mode 100644 index 000000000..e4b4dc467 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java @@ -0,0 +1,142 @@ +/* ======================================================================== + * 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.expression; + +import java.util.ArrayDeque; +import java.util.Deque; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TVariable; + +// https://en.wikipedia.org/wiki/Shunting-yard_algorithm +// https://en.cppreference.com/w/c/language/operator_precedence +public class ShuntingYard { + + final private TokenStack ouputQueue = new TokenStack(); + final private Deque operatorStack = new ArrayDeque(); + + public ShuntingYard(TokenIterator it, Knowledge knowledge) throws EaterException { + + while (it.hasMoreTokens()) { + final Token token = it.nextToken(); + if (token.getTokenType() == TokenType.NUMBER || token.getTokenType() == TokenType.QUOTED_STRING) { + ouputQueue.add(token); + } else if (token.getTokenType() == TokenType.FUNCTION_NAME) { + operatorStack.addFirst(token); + } else if (token.getTokenType() == TokenType.PLAIN_TEXT) { + final String name = token.getSurface(); + final TVariable variable = knowledge.getVariable(name); + if (variable == null) { + throw new EaterException("var0089 " + name); + } + ouputQueue.add(variable.getValue2().toToken()); + } else if (token.getTokenType() == TokenType.OPERATOR) { + while ((thereIsAFunctionAtTheTopOfTheOperatorStack(token) // + || thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(token) // + || theOperatorAtTheTopOfTheOperatorStackHasEqualPrecedenceAndIsLeftAssociative(token)) // + && theOperatorAtTheTopOfTheOperatorStackIsNotALeftParenthesis(token)) { + ouputQueue.add(operatorStack.removeFirst()); + } + // push it onto the operator stack. + operatorStack.addFirst(token); + } else if (token.getTokenType() == TokenType.OPEN_PAREN_FUNC) { + operatorStack.addFirst(token); + } else if (token.getTokenType() == TokenType.OPEN_PAREN_MATH) { + operatorStack.addFirst(token); + } else if (token.getTokenType() == TokenType.CLOSE_PAREN_FUNC) { + while (operatorStack.peekFirst().getTokenType() != TokenType.OPEN_PAREN_FUNC) { + ouputQueue.add(operatorStack.removeFirst()); + // System.err.println("Warning 2012"); + } + } else if (token.getTokenType() == TokenType.CLOSE_PAREN_MATH) { + while (operatorStack.peekFirst().getTokenType() != TokenType.OPEN_PAREN_MATH) { + ouputQueue.add(operatorStack.removeFirst()); + // System.err.println("Warning 2013"); + } + if (operatorStack.peekFirst().getTokenType() == TokenType.OPEN_PAREN_MATH) { + // System.err.println("Warning 4210"); + operatorStack.removeFirst(); + // throw new UnsupportedOperationException(token.toString()); + } + } else if (token.getTokenType() == TokenType.COMMA) { + // Just ignore + } else { + throw new UnsupportedOperationException(token.toString()); + } + } + + while (operatorStack.isEmpty() == false) { + final Token token = operatorStack.removeFirst(); + ouputQueue.add(token); + } + + // System.err.println("ouputQueue=" + ouputQueue); + } + + private boolean thereIsAFunctionAtTheTopOfTheOperatorStack(Token token) { + return false; + } + + private boolean thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(Token token) { + final Token top = operatorStack.peekFirst(); + if (top != null && top.getTokenType() == TokenType.OPERATOR + && top.getTokenOperator().getPrecedence() > token.getTokenOperator().getPrecedence()) { + return true; + } + return false; + } + + private boolean theOperatorAtTheTopOfTheOperatorStackHasEqualPrecedenceAndIsLeftAssociative(Token token) { + final Token top = operatorStack.peekFirst(); + if (top != null && top.getTokenType() == TokenType.OPERATOR && top.getTokenOperator().isLeftAssociativity() + && top.getTokenOperator().getPrecedence() == token.getTokenOperator().getPrecedence()) { + return true; + } + return false; + } + + private boolean theOperatorAtTheTopOfTheOperatorStackIsNotALeftParenthesis(Token token) { + final Token top = operatorStack.peekFirst(); + if (top != null && top.getTokenType() == TokenType.OPEN_PAREN_MATH) { + return true; + } + return true; + } + + public TokenStack getQueue() { + return this.ouputQueue; + } + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/TValue.java b/src/net/sourceforge/plantuml/tim/expression/TValue.java new file mode 100644 index 000000000..46b96fcba --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/TValue.java @@ -0,0 +1,171 @@ +/* ======================================================================== + * 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.expression; + +public class TValue { + + private final int intValue; + private final String stringValue; + + private TValue(int value) { + this.intValue = value; + this.stringValue = null; + } + + private TValue(String stringValue) { + if (stringValue == null) { + throw new IllegalArgumentException(); + } + this.intValue = 0; + this.stringValue = stringValue; + } + + public static TValue fromInt(int v) { + return new TValue(v); + } + + public static TValue fromBoolean(boolean b) { + return new TValue(b ? 1 : 0); + } + + @Override + public String toString() { + if (stringValue == null) { + return "" + intValue; + } + return stringValue; + } + + public static TValue fromString(Token token) { + if (token.getTokenType() != TokenType.QUOTED_STRING) { + throw new IllegalArgumentException(); + } + return new TValue(token.getSurface()); + } + + public static TValue fromString(String s) { + return new TValue(s); + } + + public static TValue fromNumber(Token token) { + if (token.getTokenType() != TokenType.NUMBER) { + throw new IllegalArgumentException(); + } + return new TValue(Integer.parseInt(token.getSurface())); + } + + public TValue add(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); + } + return new TValue(toString() + v2.toString()); + } + + public boolean isNumber() { + return this.stringValue == null; + } + + public Token toToken() { + if (isNumber()) { + return new Token(toString(), TokenType.NUMBER); + } + return new Token(toString(), TokenType.QUOTED_STRING); + } + + public TValue greaterThanOrEquals(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return fromBoolean(this.intValue >= v2.intValue); + } + return fromBoolean(toString().compareTo(v2.toString()) >= 0); + } + + public TValue greaterThan(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return fromBoolean(this.intValue > v2.intValue); + } + return fromBoolean(toString().compareTo(v2.toString()) > 0); + } + + public TValue lessThanOrEquals(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return fromBoolean(this.intValue <= v2.intValue); + } + return fromBoolean(toString().compareTo(v2.toString()) <= 0); + } + + public TValue lessThan(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return fromBoolean(this.intValue < v2.intValue); + } + return fromBoolean(toString().compareTo(v2.toString()) < 0); + } + + public TValue equalsOperation(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return fromBoolean(this.intValue == v2.intValue); + } + return fromBoolean(toString().compareTo(v2.toString()) == 0); + } + + public TValue notEquals(TValue v2) { + if (this.isNumber() && v2.isNumber()) { + return fromBoolean(this.intValue != v2.intValue); + } + return fromBoolean(toString().compareTo(v2.toString()) != 0); + } + + public boolean toBoolean() { + if (this.isNumber()) { + return this.intValue != 0; + } + return toString().length() > 0; + } + + public TValue logicalAnd(TValue v2) { + return fromBoolean(this.toBoolean() && v2.toBoolean()); + } + + public TValue logicalOr(TValue v2) { + return fromBoolean(this.toBoolean() || v2.toBoolean()); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/Token.java b/src/net/sourceforge/plantuml/tim/expression/Token.java new file mode 100644 index 000000000..d9d5e81d7 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/Token.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.tim.expression; + +public class Token { + + private final String surface; + private final TokenType tokenType; + + @Override + public String toString() { + return tokenType + "{" + surface + "}"; + } + + public Token(char surface, TokenType tokenType) { + this("" + surface, tokenType); + } + + public Token(String surface, TokenType tokenType) { + this.surface = surface; + this.tokenType = tokenType; + } + + public TokenOperator getTokenOperator() { + if (this.tokenType != TokenType.OPERATOR) { + throw new IllegalStateException(); + } + final char ch2 = surface.length() > 1 ? surface.charAt(1) : 0; + return TokenOperator.getTokenOperator(surface.charAt(0), ch2); + } + + public final String getSurface() { + return surface; + } + + public final TokenType getTokenType() { + return tokenType; + } + + public Token muteToFunction() { + if (this.tokenType != TokenType.PLAIN_TEXT) { + throw new IllegalStateException(); + } + return new Token(surface, TokenType.FUNCTION_NAME); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenIterator.java b/src/net/sourceforge/plantuml/tim/expression/TokenIterator.java new file mode 100644 index 000000000..5f3e8a23a --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/TokenIterator.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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.expression; + +public interface TokenIterator { + + public Token nextToken(); + + public Token peekToken(); + + public boolean hasMoreTokens(); + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java b/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java new file mode 100644 index 000000000..5bbee81fd --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/TokenOperator.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * 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.expression; + + +//https://en.cppreference.com/w/c/language/operator_precedence + +public enum TokenOperator { + MULTIPLICATION(100 - 3, "*") { + public TValue operate(TValue v1, TValue v2) { + return v1.multiply(v2); + } + }, + ADDITION(100 - 4, "+") { + public TValue operate(TValue v1, TValue v2) { + return v1.add(v2); + } + }, + LESS_THAN(100 - 6, "<") { + public TValue operate(TValue v1, TValue v2) { + return v1.lessThan(v2); + } + }, + GREATER_THAN(100 - 6, ">") { + public TValue operate(TValue v1, TValue v2) { + return v1.greaterThan(v2); + } + }, + LESS_THAN_OR_EQUALS(100 - 6, "<=") { + public TValue operate(TValue v1, TValue v2) { + return v1.lessThanOrEquals(v2); + } + }, + GREATER_THAN_OR_EQUALS(100 - 6, ">=") { + public TValue operate(TValue v1, TValue v2) { + return v1.greaterThanOrEquals(v2); + } + }, + EQUALS(100 - 7, "==") { + public TValue operate(TValue v1, TValue v2) { + return v1.equalsOperation(v2); + } + }, + NOT_EQUALS(100 - 7, "!=") { + public TValue operate(TValue v1, TValue v2) { + return v1.notEquals(v2); + } + }, + LOGICAL_AND(100 - 11, "&&") { + public TValue operate(TValue v1, TValue v2) { + return v1.logicalAnd(v2); + } + }, + LOGICAL_OR(100 - 12, "||") { + public TValue operate(TValue v1, TValue v2) { + return v1.logicalOr(v2); + } + }, + ; + + private final int precedence; + private final String display; + + private TokenOperator(int precedence, String display) { + this.precedence = precedence; + this.display = display; + } + + public boolean isLeftAssociativity() { + return true; + } + + public static TokenOperator getTokenOperator(char ch, char ch2) { + for (TokenOperator op : TokenOperator.values()) { + if (op.display.length() == 2 && op.display.charAt(0) == ch && op.display.charAt(1) == ch2) { + return op; + } + } + for (TokenOperator op : TokenOperator.values()) { + if (op.display.length() == 1 && op.display.charAt(0) == ch) { + return op; + } + } + return null; + } + + public final int getPrecedence() { + return precedence; + } + + public abstract TValue operate(TValue v1, TValue v2); + + public final String getDisplay() { + return display; + } +} diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java new file mode 100644 index 000000000..d8b698140 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java @@ -0,0 +1,217 @@ +/* ======================================================================== + * 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.expression; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.tim.Eater; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TMemory; + +public class TokenStack { + + final private List tokens; + + public TokenStack() { + this(new ArrayList()); + } + + private TokenStack(List list) { + this.tokens = list; + } + + public TokenStack subTokenStack(int i) { + return new TokenStack(Collections.unmodifiableList(tokens.subList(i, tokens.size()))); + } + + @Override + public String toString() { + return tokens.toString(); + } + + public void add(Token token) { + this.tokens.add(token); + } + + public TokenStack withoutSpace() { + final TokenStack result = new TokenStack(); + for (Token token : tokens) { + if (token.getTokenType() != TokenType.SPACES) { + result.add(token); + } + } + return result; + } + + static public TokenStack eatUntilCloseParenthesisOrComma(Eater eater) throws EaterException { + final TokenStack result = new TokenStack(); + int level = 0; + while (true) { + eater.skipSpaces(); + final char ch = eater.peekChar(); + if (ch == 0) { + throw new EaterException("until001"); + } + if (level == 0 && (ch == ',' || ch == ')')) { + return result; + } + final Token token = TokenType.eatOneToken(eater); + final TokenType type = token.getTokenType(); + if (type == TokenType.OPEN_PAREN_MATH) { + level++; + } else if (type == TokenType.CLOSE_PAREN_MATH) { + level--; + } + result.add(token); + } + } + + static public void eatUntilCloseParenthesisOrComma(TokenIterator it) throws EaterException { + int level = 0; + while (true) { + final Token ch = it.peekToken(); + if (ch == null) { + throw new EaterException("until002"); + } + final TokenType typech = ch.getTokenType(); + if (level == 0 && (typech == TokenType.COMMA || typech == TokenType.CLOSE_PAREN_MATH) + || typech == TokenType.CLOSE_PAREN_FUNC) { + return; + } + final Token token = it.nextToken(); + final TokenType type = token.getTokenType(); + if (type == TokenType.OPEN_PAREN_MATH || type == TokenType.OPEN_PAREN_FUNC) { + level++; + } else if (type == TokenType.CLOSE_PAREN_MATH || type == TokenType.CLOSE_PAREN_FUNC) { + level--; + } + } + } + + private int countFunctionArg(TokenIterator it) throws EaterException { + // return 42; + final TokenType type1 = it.peekToken().getTokenType(); + if (type1 == TokenType.CLOSE_PAREN_MATH || type1 == TokenType.CLOSE_PAREN_FUNC) { + return 0; + } + int result = 1; + while (it.hasMoreTokens()) { + eatUntilCloseParenthesisOrComma(it); + final Token token = it.nextToken(); + final TokenType type = token.getTokenType(); + if (type == TokenType.CLOSE_PAREN_MATH || type == TokenType.CLOSE_PAREN_FUNC) { + return result; + } else if (type == TokenType.COMMA) { + result++; + } else { + throw new EaterException("count13"); + } + } + throw new EaterException("count12"); + } + + public void guessFunctions() throws EaterException { + final Deque open = new ArrayDeque(); + final Map parens = new HashMap(); + for (int i = 0; i < tokens.size(); i++) { + final Token token = tokens.get(i); + if (token.getTokenType().equals(TokenType.OPEN_PAREN_MATH)) { + open.addFirst(i); + } else if (token.getTokenType().equals(TokenType.CLOSE_PAREN_MATH)) { + parens.put(open.pollFirst(), i); + } + } + // System.err.println("before=" + toString()); + // System.err.println("guessFunctions2" + parens); + for (Map.Entry ids : parens.entrySet()) { + final int iopen = ids.getKey(); + final int iclose = ids.getValue(); + assert tokens.get(iopen).getTokenType() == TokenType.OPEN_PAREN_MATH; + assert tokens.get(iclose).getTokenType() == TokenType.CLOSE_PAREN_MATH; + if (iopen > 0 && tokens.get(iopen - 1).getTokenType() == TokenType.PLAIN_TEXT) { + tokens.set(iopen - 1, new Token(tokens.get(iopen - 1).getSurface(), TokenType.FUNCTION_NAME)); + final int nbArg = countFunctionArg(subTokenStack(iopen + 1).tokenIterator()); + tokens.set(iopen, new Token("" + nbArg, TokenType.OPEN_PAREN_FUNC)); + tokens.set(iclose, new Token(")", TokenType.CLOSE_PAREN_FUNC)); + } + } + // System.err.println("after=" + toString()); + } + + class InternalIterator implements TokenIterator { + + private int pos = 0; + + public Token peekToken() { + return tokens.get(pos); + } + + public Token nextToken() { + if (hasMoreTokens() == false) { + return null; + } + return tokens.get(pos++); + } + + public boolean hasMoreTokens() { + return pos < tokens.size(); + } + + } + + public TokenIterator tokenIterator() { + return new InternalIterator(); + } + + public TValue getResult(TContext context, TMemory memory) throws EaterException { + final Knowledge knowledge = context.asKnowledge(memory); + final TokenStack tmp = withoutSpace(); + tmp.guessFunctions(); + final TokenIterator it = tmp.tokenIterator(); + final ShuntingYard shuntingYard = new ShuntingYard(it, knowledge); + final ReversePolishInterpretor rpn = new ReversePolishInterpretor(shuntingYard.getQueue(), knowledge, memory, + context); + return rpn.getResult(); + + } + +} diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenType.java b/src/net/sourceforge/plantuml/tim/expression/TokenType.java new file mode 100644 index 000000000..20af39b1f --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/expression/TokenType.java @@ -0,0 +1,114 @@ +/* ======================================================================== + * 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.expression; + +import net.sourceforge.plantuml.tim.Eater; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.TLineType; + +public enum TokenType { + QUOTED_STRING, OPERATOR, OPEN_PAREN_MATH, COMMA, CLOSE_PAREN_MATH, NUMBER, PLAIN_TEXT, SPACES, FUNCTION_NAME, OPEN_PAREN_FUNC, CLOSE_PAREN_FUNC; + + private boolean isSingleChar1() { + return this == OPEN_PAREN_MATH || this == COMMA || this == CLOSE_PAREN_MATH; + } + + private static boolean isPlainTextBreak(char ch, char ch2) { + final TokenType tmp = fromChar(ch, ch2); + if (tmp.isSingleChar1() || tmp == TokenType.OPERATOR || tmp == SPACES) { + return true; + } + return false; + } + + private static TokenType fromChar(char ch, char ch2) { + TokenType result = PLAIN_TEXT; + if (TLineType.isQuote(ch)) { + result = QUOTED_STRING; + } else if (TokenOperator.getTokenOperator(ch, ch2) != null) { + result = OPERATOR; + } else if (ch == '(') { + result = OPEN_PAREN_MATH; + } else if (ch == ')') { + result = CLOSE_PAREN_MATH; + } else if (ch == ',') { + result = COMMA; + } else if (TLineType.isLatinDigit(ch)) { + result = NUMBER; + } else if (TLineType.isSpaceChar(ch)) { + result = SPACES; + } + return result; + } + + final static public Token eatOneToken(Eater eater) throws EaterException { + final char ch = eater.peekChar(); + if (ch == 0) { + return null; + } + final TokenOperator tokenOperator = TokenOperator.getTokenOperator(ch, eater.peekCharN2()); + if (TLineType.isQuote(ch)) { + return new Token(eater.eatAndGetQuotedString(), TokenType.QUOTED_STRING); + } else if (tokenOperator != null) { + if (tokenOperator.getDisplay().length() == 1) { + return new Token(eater.eatOneChar(), TokenType.OPERATOR); + } + return new Token("" + eater.eatOneChar() + eater.eatOneChar(), TokenType.OPERATOR); + } else if (ch == '(') { + return new Token(eater.eatOneChar(), TokenType.OPEN_PAREN_MATH); + } else if (ch == ')') { + return new Token(eater.eatOneChar(), TokenType.CLOSE_PAREN_MATH); + } else if (ch == ',') { + return new Token(eater.eatOneChar(), TokenType.COMMA); + } else if (TLineType.isLatinDigit(ch)) { + return new Token(eater.eatAndGetNumber(), TokenType.NUMBER); + } else if (TLineType.isSpaceChar(ch)) { + return new Token(eater.eatAndGetSpaces(), TokenType.SPACES); + } + return new Token(eatAndGetTokenPlainText(eater), TokenType.PLAIN_TEXT); + } + + static private String eatAndGetTokenPlainText(Eater eater) throws EaterException { + final StringBuilder result = new StringBuilder(); + while (true) { + final char ch = eater.peekChar(); + if (ch == 0 || TokenType.isPlainTextBreak(ch, eater.peekCharN2())) { + return result.toString(); + } + result.append(eater.eatOneChar()); + } + } + +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java new file mode 100644 index 000000000..a0b2f1d52 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.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.TFunctionType; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class Strlen implements TFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%strlen", 1); + } + + public boolean canCover(int nbArg) { + 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/timingdiagram/AbstractPlayer.java b/src/net/sourceforge/plantuml/timingdiagram/AbstractPlayer.java index 49f8c2e13..11a4f7da6 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/AbstractPlayer.java +++ b/src/net/sourceforge/plantuml/timingdiagram/AbstractPlayer.java @@ -35,7 +35,6 @@ package net.sourceforge.plantuml.timingdiagram; import java.awt.geom.Dimension2D; -import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -43,31 +42,21 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; -import net.sourceforge.plantuml.Dimension2DDouble; -import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.cucadiagram.Display; -import net.sourceforge.plantuml.graphic.FontConfiguration; -import net.sourceforge.plantuml.graphic.HorizontalAlignment; 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.color.Colors; -import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; -public abstract class AbstractPlayer implements Player { +public abstract class AbstractPlayer extends ReallyAbstractPlayer implements Player { - // private final String code; - private final Display full; - protected final ISkinParam skinParam; - protected final TimingRuler ruler; private String initialState; private final Set changes = new TreeSet(); @@ -75,26 +64,21 @@ public abstract class AbstractPlayer implements Player { protected final List notes = new ArrayList(); protected final Map statesLabel = new LinkedHashMap(); - public AbstractPlayer(String full, ISkinParam skinParam, TimingRuler ruler) { - // this.code = code; - this.full = Display.getWithNewlines(full); - this.skinParam = skinParam; - this.ruler = ruler; + public AbstractPlayer(TitleStrategy titleStrategy, String full, ISkinParam skinParam, TimingRuler ruler) { + super(titleStrategy, full, skinParam, ruler); } protected abstract TimeDrawing buildDrawing(); - private FontConfiguration getFontConfiguration() { - return new FontConfiguration(skinParam, FontParam.TIMING, null); - } - - public void drawTitle(UGraphic ug) { - final TextBlock title = getTitle(); - title.drawU(ug); - final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); - drawLine(ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(new UStroke(1.0)), -TimingDiagram.marginX1, - dimTitle.getHeight() + 1, dimTitle.getWidth() + 1, dimTitle.getHeight() + 1, - dimTitle.getWidth() + 1 + 10, 0); + public void drawFrameTitle(UGraphic ug) { + if (titleStrategy == TitleStrategy.IN_FRAME) { + final TextBlock title = getTitle(); + title.drawU(ug); + final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); + drawLine(ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(new UStroke(1.0)), -TimingDiagram.marginX1, + dimTitle.getHeight() + 1, dimTitle.getWidth() + 1, dimTitle.getHeight() + 1, + dimTitle.getWidth() + 1 + 10, 0); + } } public void drawContent(UGraphic ug) { @@ -103,12 +87,25 @@ public abstract class AbstractPlayer implements Player { } public void drawLeftHeader(UGraphic ug) { + if (titleStrategy == TitleStrategy.IN_LEFT_HEADER) { + final StringBounder stringBounder = ug.getStringBounder(); + final TextBlock title = getTitle(); + final Dimension2D dim = title.calculateDimension(stringBounder); + final double y = (getHeight(stringBounder) - dim.getHeight()) / 2; + title.drawU(ug.apply(new UTranslate(0, y))); + ug = ug.apply(new UTranslate(dim.getWidth() + 5, 0)); + } ug = ug.apply(getTranslateForTimeDrawing(ug.getStringBounder())); getTimeDrawing().getWidthHeader(ug.getStringBounder()).drawU(ug); } public double getWidthHeader(StringBounder stringBounder) { - return getTimeDrawing().getWidthHeader(stringBounder).calculateDimension(stringBounder).getWidth(); + final Dimension2D dimHeader1 = getTimeDrawing().getWidthHeader(stringBounder).calculateDimension(stringBounder); + if (titleStrategy == TitleStrategy.IN_LEFT_HEADER) { + final Dimension2D dimTitle = getTitle().calculateDimension(stringBounder); + return dimTitle.getWidth() + 5 + dimHeader1.getWidth(); + } + return dimHeader1.getWidth(); } private void drawLine(UGraphic ug, double... coord) { @@ -123,12 +120,11 @@ public abstract class AbstractPlayer implements Player { } private UTranslate getTranslateForTimeDrawing(StringBounder stringBounder) { - final TextBlock title = getTitle(); - return new UTranslate(0, title.calculateDimension(stringBounder).getHeight() * 2); - } - - private TextBlock getTitle() { - return full.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); + if (titleStrategy == TitleStrategy.IN_FRAME) { + final TextBlock title = getTitle(); + return new UTranslate(0, title.calculateDimension(stringBounder).getHeight() * 2); + } + return new UTranslate(0, 12); } private TimeDrawing cached; @@ -154,8 +150,11 @@ public abstract class AbstractPlayer implements Player { } public double getHeight(StringBounder stringBounder) { - final TextBlock title = getTitle(); final double zoneHeight = getZoneHeight(stringBounder); + if (titleStrategy == TitleStrategy.IN_LEFT_HEADER) { + return zoneHeight; + } + final TextBlock title = getTitle(); return title.calculateDimension(stringBounder).getHeight() * 2 + zoneHeight; } diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandAtPlayer.java b/src/net/sourceforge/plantuml/timingdiagram/CommandAtPlayer.java index a5855555d..7e2244c0d 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandAtPlayer.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandAtPlayer.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -55,7 +56,7 @@ public class CommandAtPlayer extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.get("PLAYER", 0); final Player player = diagram.getPlayer(code); if (player == null) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandAtTime.java b/src/net/sourceforge/plantuml/timingdiagram/CommandAtTime.java index e8995f9f9..4ce9de4a5 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandAtTime.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandAtTime.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ public class CommandAtTime extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final TimeTick timeTick = TimeTickBuilder.parseTimeTick("TIME", arg, diagram); if (timeTick == null) { return CommandExecutionResult.error("What time?"); diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandBinary.java b/src/net/sourceforge/plantuml/timingdiagram/CommandBinary.java index 5a9161ad6..92e498986 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandBinary.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandBinary.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandBinary extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.get("CODE", 0); final String full = arg.get("FULL", 0); return diagram.createBinary(code, full); diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java index 316494158..93d4b7b00 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByPlayerCode.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -59,7 +60,7 @@ public class CommandChangeStateByPlayerCode extends CommandChangeState { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.get("CODE", 0); final Player player = diagram.getPlayer(code); if (player == null) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java index 655da4304..c473e6bf3 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandChangeStateByTime.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -60,7 +61,7 @@ public class CommandChangeStateByTime extends CommandChangeState { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final Player player = diagram.getLastPlayer(); if (player == null) { return CommandExecutionResult.error("Missing @ line before this"); diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandClock.java b/src/net/sourceforge/plantuml/timingdiagram/CommandClock.java index 46a06242a..0e3db3500 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandClock.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandClock.java @@ -35,10 +35,12 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexResult; public class CommandClock extends SingleLineCommand2 { @@ -51,20 +53,22 @@ public class CommandClock extends SingleLineCommand2 { return new RegexConcat(new RegexLeaf("^"), // new RegexLeaf("TYPE", // "(clock)[%s]+"), // - // new RegexLeaf("FULL", "[%g]([^%g]+)[%g]"), // - // new RegexLeaf("[%s]+as[%s]+"), // new RegexLeaf("CODE", "([\\p{L}0-9_.@]+)"), // - new RegexLeaf("[%s]+with[%s]+period[%s]+"), // - new RegexLeaf("PERIOD", "([0-9]+)"), // + new RegexLeaf("PERIOD", "[%s]+with[%s]+period[%s]+([0-9]+)"), // + new RegexOptional(new RegexLeaf("PULSE", "[%s]+pulse[%s]+([0-9]+)")), // new RegexLeaf("$")); } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.get("CODE", 0); - // final String full = arg.get("FULL", 0); final int period = Integer.parseInt(arg.get("PERIOD", 0)); - return diagram.createClock(code, code, period); + final String pulseString = arg.get("PULSE", 0); + int pulse = 0; + if (pulseString != null) { + pulse = Integer.parseInt(pulseString); + } + return diagram.createClock(code, code, period, pulse); } } diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandConstraint.java b/src/net/sourceforge/plantuml/timingdiagram/CommandConstraint.java index e6f66e09e..530447a43 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandConstraint.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandConstraint.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -61,7 +62,7 @@ public class CommandConstraint extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String part1 = arg.get("PART1", 0); final Player player1; if (part1 == null) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateLong.java b/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateLong.java index 018c8bc66..1a02ecf4d 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateLong.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateLong.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandDefineStateLong extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String playerCode = arg.get("PLAYER", 0); final Player player = diagram.getPlayer(playerCode); if (player == null) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateShort.java b/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateShort.java index 4ace2d78f..5a5fdc831 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateShort.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandDefineStateShort.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.timingdiagram; import java.util.StringTokenizer; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -59,7 +60,7 @@ public class CommandDefineStateShort extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String playerCode = arg.get("PLAYER", 0); final Player player = diagram.getPlayer(playerCode); if (player == null) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandHideTimeAxis.java b/src/net/sourceforge/plantuml/timingdiagram/CommandHideTimeAxis.java new file mode 100644 index 000000000..06480e3cd --- /dev/null +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandHideTimeAxis.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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.timingdiagram; + +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandHideTimeAxis extends SingleLineCommand2 { + + public CommandHideTimeAxis() { + super(getRegexConcat()); + } + + private static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("hide[%s]+time.?axis"), // + new RegexLeaf("$")); + } + + @Override + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { + return diagram.hideTimeAxis(); + } + +} diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandNote.java b/src/net/sourceforge/plantuml/timingdiagram/CommandNote.java index 5c9e07c66..674e5aea4 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandNote.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandNote.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -60,7 +61,7 @@ public class CommandNote extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.get("CODE", 0); final Player player = diagram.getPlayer(code); if (player == null) { diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandNoteLong.java b/src/net/sourceforge/plantuml/timingdiagram/CommandNoteLong.java index 5dbda5e7b..25180a5fc 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandNoteLong.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandNoteLong.java @@ -35,7 +35,6 @@ */ package net.sourceforge.plantuml.timingdiagram; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; @@ -58,7 +57,7 @@ public class CommandNoteLong extends CommandMultilines2 { protected CommandExecutionResult executeNow(final TimingDiagram diagram, BlocLines lines) { - final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.getFirst499())); + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst499().getStringTrimmed()); lines = lines.subExtract(1, 1); lines = lines.removeEmptyColumns(); final String code = line0.get("CODE", 0); diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandRobustConcise.java b/src/net/sourceforge/plantuml/timingdiagram/CommandRobustConcise.java index 3d5cb3f6a..54463277d 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandRobustConcise.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandRobustConcise.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -58,7 +59,7 @@ public class CommandRobustConcise extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final String code = arg.get("CODE", 0); final String full = arg.get("FULL", 0); final TimingStyle type = TimingStyle.valueOf(arg.get("TYPE", 0).toUpperCase()); diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandScalePixel.java b/src/net/sourceforge/plantuml/timingdiagram/CommandScalePixel.java index 6ee5f183d..a8445402a 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandScalePixel.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandScalePixel.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -59,7 +60,7 @@ public class CommandScalePixel extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final long tick = Long.parseLong(arg.get("TICK", 0)); final long pixel = Long.parseLong(arg.get("PIXEL", 0)); diagram.scaleInPixels(tick, pixel); diff --git a/src/net/sourceforge/plantuml/timingdiagram/CommandTimeMessage.java b/src/net/sourceforge/plantuml/timingdiagram/CommandTimeMessage.java index fc47e8412..62e6a881f 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/CommandTimeMessage.java +++ b/src/net/sourceforge/plantuml/timingdiagram/CommandTimeMessage.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -67,7 +68,7 @@ public class CommandTimeMessage extends SingleLineCommand2 { } @Override - final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) { + final protected CommandExecutionResult executeArg(TimingDiagram diagram, LineLocation location, RegexResult arg) { final Player player1 = diagram.getPlayer(arg.get("PART1", 0)); if (player1 == null) { return CommandExecutionResult.error("No such element: " + arg.get("PART1", 0)); diff --git a/src/net/sourceforge/plantuml/timingdiagram/Player.java b/src/net/sourceforge/plantuml/timingdiagram/Player.java index a1f008711..bff98d9a3 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/Player.java +++ b/src/net/sourceforge/plantuml/timingdiagram/Player.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml.timingdiagram; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -51,7 +50,7 @@ public interface Player extends TimeProjected { public void createConstraint(TimeTick tick1, TimeTick tick2, String message); - public void drawTitle(UGraphic ug); + public void drawFrameTitle(UGraphic ug); public void drawContent(UGraphic ug); @@ -60,5 +59,8 @@ public interface Player extends TimeProjected { public double getWidthHeader(StringBounder stringBounder); public double getHeight(StringBounder stringBounder); + + public double getFirstColumnWidth(StringBounder stringBounder); + } diff --git a/src/net/sourceforge/plantuml/timingdiagram/PlayerBinary.java b/src/net/sourceforge/plantuml/timingdiagram/PlayerBinary.java index e0c5051ab..339dd7d28 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/PlayerBinary.java +++ b/src/net/sourceforge/plantuml/timingdiagram/PlayerBinary.java @@ -34,6 +34,7 @@ */ package net.sourceforge.plantuml.timingdiagram; +import java.awt.geom.Dimension2D; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; @@ -44,20 +45,20 @@ import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.SymbolContext; +import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class PlayerBinary implements Player { +public class PlayerBinary extends ReallyAbstractPlayer implements Player { private static final int HEIGHT = 30; - private final TimingRuler ruler; private final SortedMap values = new TreeMap(); - public PlayerBinary(ISkinParam skinParam, TimingRuler ruler) { - this.ruler = ruler; + public PlayerBinary(TitleStrategy titleStrategy, String code, ISkinParam skinParam, TimingRuler ruler) { + super(titleStrategy, code, skinParam, ruler); } public double getHeight(StringBounder stringBounder) { @@ -95,7 +96,7 @@ public class PlayerBinary implements Player { private final double ymargin = 8; - public void drawTitle(UGraphic ug) { + public void drawFrameTitle(UGraphic ug) { } private double getYpos(boolean state) { @@ -119,11 +120,15 @@ public class PlayerBinary implements Player { } public void drawLeftHeader(UGraphic ug) { - + final StringBounder stringBounder = ug.getStringBounder(); + final TextBlock title = getTitle(); + final Dimension2D dim = title.calculateDimension(stringBounder); + final double y = (getHeight(stringBounder) - dim.getHeight()) / 2; + title.drawU(ug.apply(new UTranslate(0, y))); } public double getWidthHeader(StringBounder stringBounder) { - return 0; + return getTitle().calculateDimension(stringBounder).getWidth() + 5; } } diff --git a/src/net/sourceforge/plantuml/timingdiagram/PlayerClock.java b/src/net/sourceforge/plantuml/timingdiagram/PlayerClock.java index 90859375e..5afc33712 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/PlayerClock.java +++ b/src/net/sourceforge/plantuml/timingdiagram/PlayerClock.java @@ -48,17 +48,18 @@ import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class PlayerClock implements Player { +public class PlayerClock extends ReallyAbstractPlayer implements Player { - private final TimingRuler ruler; private final int period; + private final int pulse; - public PlayerClock(ISkinParam skinParam, TimingRuler ruler, int period) { - this.ruler = ruler; + public PlayerClock(TitleStrategy titleStrategy, ISkinParam skinParam, TimingRuler ruler, int period, int pulse) { + super(titleStrategy, "", skinParam, ruler); this.period = period; + this.pulse = pulse; } - public double getHeight(StringBounder stringBounder) { + public double getHeight(StringBounder striWngBounder) { return 30; } @@ -88,7 +89,7 @@ public class PlayerClock implements Player { private final double ymargin = 8; - public void drawTitle(UGraphic ug) { + public void drawFrameTitle(UGraphic ug) { } public void drawContent(UGraphic ug) { @@ -97,20 +98,32 @@ public class PlayerClock implements Player { int i = 0; double lastx = -Double.MAX_VALUE; while (i < 1000) { - final double x = ruler.getPosInPixel(new BigDecimal(i * period)) / 2; + final double x = ruler.getPosInPixel(new BigDecimal(i * period)); if (x > ruler.getWidth()) { return; } i++; if (x > lastx) { + final double dx = x - lastx; + final ULine hline1 = new ULine(dx * getPulseCoef(), 0); + final ULine hline2 = new ULine(dx * (1 - getPulseCoef()), 0); ug.apply(new UTranslate(lastx, ymargin)).draw(vline); - ug.apply(new UTranslate(lastx, i % 2 == 0 ? ymargin : ymargin + vline.getDY())).draw( - new ULine(x - lastx, 0)); + ug.apply(new UTranslate(lastx, ymargin)).draw(hline1); + final double x2 = lastx + dx * getPulseCoef(); + ug.apply(new UTranslate(x2, ymargin)).draw(vline); + ug.apply(new UTranslate(x2, ymargin + vline.getDY())).draw(hline2); } lastx = x; } } + private double getPulseCoef() { + if (pulse == 0) { + return 0.5; + } + return 1.0 * pulse / period; + } + public void drawLeftHeader(UGraphic ug) { } diff --git a/src/net/sourceforge/plantuml/timingdiagram/PlayerConcise.java b/src/net/sourceforge/plantuml/timingdiagram/PlayerConcise.java index 5e8d2e35c..adcb4722a 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/PlayerConcise.java +++ b/src/net/sourceforge/plantuml/timingdiagram/PlayerConcise.java @@ -44,8 +44,8 @@ public class PlayerConcise extends AbstractPlayer { return result; } - public PlayerConcise(String full, ISkinParam skinParam, TimingRuler ruler) { - super(full, skinParam, ruler); + public PlayerConcise(TitleStrategy titleStrategy, String full, ISkinParam skinParam, TimingRuler ruler) { + super(titleStrategy, full, skinParam, ruler); } } diff --git a/src/net/sourceforge/plantuml/timingdiagram/PlayerRobust.java b/src/net/sourceforge/plantuml/timingdiagram/PlayerRobust.java index fdc44b45a..1e864b9a3 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/PlayerRobust.java +++ b/src/net/sourceforge/plantuml/timingdiagram/PlayerRobust.java @@ -44,8 +44,8 @@ public class PlayerRobust extends AbstractPlayer { return result; } - public PlayerRobust(String full, ISkinParam skinParam, TimingRuler ruler) { - super(full, skinParam, ruler); + public PlayerRobust(TitleStrategy titleStrategy, String full, ISkinParam skinParam, TimingRuler ruler) { + super(titleStrategy, full, skinParam, ruler); } } diff --git a/src/net/sourceforge/plantuml/timingdiagram/ReallyAbstractPlayer.java b/src/net/sourceforge/plantuml/timingdiagram/ReallyAbstractPlayer.java new file mode 100644 index 000000000..9d44b7f7f --- /dev/null +++ b/src/net/sourceforge/plantuml/timingdiagram/ReallyAbstractPlayer.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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.timingdiagram; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; + +public abstract class ReallyAbstractPlayer implements Player { + + protected final ISkinParam skinParam; + protected final TimingRuler ruler; + protected final TitleStrategy titleStrategy; + private final Display title; + + public ReallyAbstractPlayer(TitleStrategy titleStrategy, String title, ISkinParam skinParam, TimingRuler ruler) { + this.skinParam = skinParam; + this.ruler = ruler; + this.titleStrategy = titleStrategy; + this.title = Display.getWithNewlines(title); + } + + public double getFirstColumnWidth(StringBounder stringBounder) { + return 40; + } + + + + final protected FontConfiguration getFontConfiguration() { + return new FontConfiguration(skinParam, FontParam.TIMING, null); + } + + final protected TextBlock getTitle() { + return title.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); + } + + private TextBlock createTextBlock(String value) { + final Display display = Display.getWithNewlines(value); + return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); + } + + + +} diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java b/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java index de667bd66..8af80a6b6 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimeArrow.java @@ -42,7 +42,6 @@ import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.WithLinkType; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; -import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java b/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java index 433a501b3..b64ff6daf 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java @@ -34,7 +34,6 @@ */ package net.sourceforge.plantuml.timingdiagram; -import java.awt.Font; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java index 094e53a06..c761c4159 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java @@ -70,12 +70,18 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class TimingDiagram extends UmlDiagram implements Clocks { + private TitleStrategy getTitleStrategy() { + // return TitleStrategy.IN_LEFT_HEADER; + return TitleStrategy.IN_FRAME; + } + private final Map players = new LinkedHashMap(); private final Map clocks = new HashMap(); private final List messages = new ArrayList(); private final TimingRuler ruler = new TimingRuler(getSkinParam()); private TimeTick now; private Player lastPlayer; + private boolean drawTimeAxis = true; public DiagramDescription getDescription() { return new DiagramDescription("(Timing Diagram)"); @@ -151,14 +157,16 @@ public class TimingDiagram extends UmlDiagram implements Clocks { ruler.draw0(ug.apply(new UTranslate(withBeforeRuler, 0)), getUTranslateForPlayer(null, stringBounder).getDy()); for (Player player : players.values()) { final UGraphic playerUg = ug.apply(getUTranslateForPlayer(player, stringBounder)); - player.drawTitle(playerUg); + player.drawFrameTitle(playerUg); player.drawContent(playerUg.apply(new UTranslate(withBeforeRuler, 0))); player.drawLeftHeader(playerUg); playerUg.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(borderStroke) .apply(new UTranslate(-marginX1, 0)).draw(new ULine(totalWith, 0)); } ug = ug.apply(new UTranslate(withBeforeRuler, 0)); - ruler.draw(ug.apply(lastTranslate)); + if (this.drawTimeAxis) { + ruler.drawTimeAxis(ug.apply(lastTranslate)); + } for (TimeMessage timeMessage : messages) { drawMessages(ug, timeMessage); } @@ -173,6 +181,15 @@ public class TimingDiagram extends UmlDiagram implements Clocks { return width; } + private double getFirstColumnWidth(StringBounder stringBounder) { + double width = 0; + for (Player player : players.values()) { + width = Math.max(width, player.getFirstColumnWidth(stringBounder)); + + } + return width; + } + private void drawMessages(UGraphic ug, TimeMessage message) { final Player player1 = message.getPlayer1(); final Player player2 = message.getPlayer2(); @@ -208,14 +225,14 @@ public class TimingDiagram extends UmlDiagram implements Clocks { } public CommandExecutionResult createRobustConcise(String code, String full, TimingStyle type) { - final Player player = type.createPlayer(full, getSkinParam(), ruler); + final Player player = type.createPlayer(getTitleStrategy(), full, getSkinParam(), ruler); players.put(code, player); lastPlayer = player; return CommandExecutionResult.ok(); } - public CommandExecutionResult createClock(String code, String full, int period) { - final PlayerClock player = new PlayerClock(getSkinParam(), ruler, period); + public CommandExecutionResult createClock(String code, String full, int period, int pulse) { + final PlayerClock player = new PlayerClock(getTitleStrategy(), getSkinParam(), ruler, period, pulse); players.put(code, player); clocks.put(code, player); final TimeTick tick = new TimeTick(new BigDecimal(period)); @@ -224,7 +241,7 @@ public class TimingDiagram extends UmlDiagram implements Clocks { } public CommandExecutionResult createBinary(String code, String full) { - final Player player = new PlayerBinary(getSkinParam(), ruler); + final Player player = new PlayerBinary(getTitleStrategy(), code, getSkinParam(), ruler); players.put(code, player); return CommandExecutionResult.ok(); } @@ -273,4 +290,9 @@ public class TimingDiagram extends UmlDiagram implements Clocks { ruler.scaleInPixels(tick, pixel); } + public CommandExecutionResult hideTimeAxis() { + this.drawTimeAxis = false; + return CommandExecutionResult.ok(); + } + } diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java index 0f36e89bd..9dded158f 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagramFactory.java @@ -70,6 +70,7 @@ public class TimingDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandNoteLong()); cmds.add(new CommandConstraint()); cmds.add(new CommandScalePixel()); + cmds.add(new CommandHideTimeAxis()); return cmds; } diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java b/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java index ffa3a5da5..178e87177 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingRuler.java @@ -124,7 +124,7 @@ public class TimingRuler { return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); } - public void draw(UGraphic ug) { + public void drawTimeAxis(UGraphic ug) { ug = ug.apply(new UStroke(2.0)).apply(new UChangeColor(HtmlColorUtils.BLACK)); final double tickHeight = 5; final ULine line = new ULine(0, tickHeight); diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingStyle.java b/src/net/sourceforge/plantuml/timingdiagram/TimingStyle.java index b3e606263..7ee519b0e 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingStyle.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingStyle.java @@ -40,12 +40,12 @@ public enum TimingStyle { ROBUST, CONCISE; - public Player createPlayer(String full, ISkinParam skinParam, TimingRuler ruler) { + public Player createPlayer(TitleStrategy titleStrategy, String full, ISkinParam skinParam, TimingRuler ruler) { if (this == ROBUST) { - return new PlayerRobust(full, skinParam, ruler); + return new PlayerRobust(titleStrategy, full, skinParam, ruler); } if (this == CONCISE) { - return new PlayerConcise(full, skinParam, ruler); + return new PlayerConcise(titleStrategy, full, skinParam, ruler); } throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/TitleStrategy.java b/src/net/sourceforge/plantuml/timingdiagram/TitleStrategy.java new file mode 100644 index 000000000..c492fb556 --- /dev/null +++ b/src/net/sourceforge/plantuml/timingdiagram/TitleStrategy.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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.timingdiagram; + +public enum TitleStrategy { + IN_FRAME, IN_LEFT_HEADER +} diff --git a/src/net/sourceforge/plantuml/turing/BFMachine.java b/src/net/sourceforge/plantuml/turing/BFMachine.java deleted file mode 100644 index 0af574372..000000000 --- a/src/net/sourceforge/plantuml/turing/BFMachine.java +++ /dev/null @@ -1,141 +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.turing; - -public class BFMachine { - - private final char cells[] = new char[30000]; - private final BFToken prg[]; - private int prgPointer; - private int pointer; - private final StringBuilder output = new StringBuilder(); - private final String input; - private int inputPointer; - - public BFMachine(String program, String input) { - prg = new BFToken[program.length() + 1]; - int i = 0; - for (int n = 0; n < program.length(); n++) { - final BFToken token = BFToken.getToken(program.charAt(n)); - if (token != null) { - prg[i++] = token; - } - } - this.input = input; - } - - public boolean run() { - for (int i = 0; i < 10000000; i++) { - if (prg[prgPointer] == null) { - return true; - } - interpret(prg[prgPointer]); - prgPointer++; - } - return false; - } - - private void interpret(BFToken token) { - switch (token) { - case NEXT: - pointer++; - break; - - case PREVIOUS: - pointer--; - break; - - case PLUS: - cells[pointer]++; - break; - - case MINUS: - cells[pointer]--; - break; - - case OUTPUT: - output(cells[pointer]); - break; - - case INPUT: - final int read = input(); - if (read != -1) { - cells[pointer] = (char) read; - } - break; - - case BRACKET_LEFT: - if (cells[pointer] == 0) { - int i = 1; - while (i > 0) { - BFToken c2 = prg[++prgPointer]; - if (c2 == BFToken.BRACKET_LEFT) - i++; - else if (c2 == BFToken.BRACKET_RIGHT) - i--; - } - } - break; - case BRACKET_RIGHT: - int i = 1; - while (i > 0) { - BFToken c2 = prg[--prgPointer]; - if (c2 == BFToken.BRACKET_LEFT) - i--; - else if (c2 == BFToken.BRACKET_RIGHT) - i++; - } - prgPointer--; - break; - } - - } - - private int input() { - if (inputPointer < input.length()) { - return input.charAt(inputPointer++); - } - return -1; - } - - private void output(char c) { - output.append(c); - } - - public String getOutput() { - return output.toString(); - } -} diff --git a/src/net/sourceforge/plantuml/ugraphic/ColorMapperIdentity.java b/src/net/sourceforge/plantuml/ugraphic/ColorMapperIdentity.java index 5adf6bb09..bc999a9d3 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ColorMapperIdentity.java +++ b/src/net/sourceforge/plantuml/ugraphic/ColorMapperIdentity.java @@ -38,6 +38,8 @@ package net.sourceforge.plantuml.ugraphic; import java.awt.Color; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlColorGradient; +import net.sourceforge.plantuml.graphic.HtmlColorMiddle; import net.sourceforge.plantuml.graphic.HtmlColorSimple; import net.sourceforge.plantuml.graphic.HtmlColorTransparent; import net.sourceforge.plantuml.graphic.HtmlColorUserDef; @@ -55,6 +57,12 @@ public class ColorMapperIdentity implements ColorMapper { // Impact on JCCKIT return Color.WHITE; } + if (color instanceof HtmlColorGradient) { + return getMappedColor(((HtmlColorGradient) color).getColor1()); + } + if (color instanceof HtmlColorMiddle) { + return ((HtmlColorMiddle) color).getMappedColor(this); + } return ((HtmlColorSimple) color).getColor999(); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/ColorMapperReverse.java b/src/net/sourceforge/plantuml/ugraphic/ColorMapperReverse.java index 25d9b02b6..28900bbc8 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ColorMapperReverse.java +++ b/src/net/sourceforge/plantuml/ugraphic/ColorMapperReverse.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.ugraphic; import java.awt.Color; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlColorMiddle; import net.sourceforge.plantuml.graphic.HtmlColorSimple; public class ColorMapperReverse implements ColorMapper { @@ -52,6 +53,9 @@ public class ColorMapperReverse implements ColorMapper { if (color == null) { return null; } + if (color instanceof HtmlColorMiddle) { + return ((HtmlColorMiddle) color).getMappedColor(this); + } return getReverse(((HtmlColorSimple) color).getColor999()); } diff --git a/src/net/sourceforge/plantuml/ugraphic/UImage.java b/src/net/sourceforge/plantuml/ugraphic/UImage.java index a3cc2648b..569cff812 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UImage.java +++ b/src/net/sourceforge/plantuml/ugraphic/UImage.java @@ -97,6 +97,40 @@ public class UImage implements UShape { if (newColor == null) { return this; } + int darkerRgb = getDarkerRgb(); + final BufferedImage copy = deepCopy2(); + for (int i = 0; i < image.getWidth(); i++) { + for (int j = 0; j < image.getHeight(); j++) { + final int color = image.getRGB(i, j); + final int rgb = getRgb(color); + final int a = getA(color); + if (a != 0 && rgb == darkerRgb) { + copy.setRGB(i, j, newColor.getRGB() + a); + } + } + } + return new UImage(copy, formula); + } + + public UImage muteTransparentColor(Color newColor) { + if (newColor == null) { + newColor = Color.WHITE; + } + final BufferedImage copy = deepCopy2(); + for (int i = 0; i < image.getWidth(); i++) { + for (int j = 0; j < image.getHeight(); j++) { + final int color = image.getRGB(i, j); + // final int rgb = getRgb(color); + final int a = getA(color); + if (a == 0) { + copy.setRGB(i, j, newColor.getRGB()); + } + } + } + return new UImage(copy, formula); + } + + private int getDarkerRgb() { int darkerRgb = -1; for (int i = 0; i < image.getWidth(); i++) { for (int j = 0; j < image.getHeight(); j++) { @@ -116,18 +150,7 @@ public class UImage implements UShape { } } } - final BufferedImage copy = deepCopy(image); - for (int i = 0; i < image.getWidth(); i++) { - for (int j = 0; j < image.getHeight(); j++) { - final int color = copy.getRGB(i, j); - final int rgb = getRgb(color); - final int a = getA(color); - if (a!=0 && rgb == darkerRgb) { - copy.setRGB(i, j, newColor.getRGB() + a); - } - } - } - return new UImage(copy, formula); + return darkerRgb; } private static final int mask_a__ = 0xFF000000; @@ -149,10 +172,21 @@ public class UImage implements UShape { // } // From https://stackoverflow.com/questions/3514158/how-do-you-clone-a-bufferedimage - private static BufferedImage deepCopy(BufferedImage bi) { + private static BufferedImage deepCopyOld(BufferedImage bi) { final ColorModel cm = bi.getColorModel(); final boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); final WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster()); return new BufferedImage(cm, raster, isAlphaPremultiplied, null); } + + private BufferedImage deepCopy2() { + final BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); + for (int i = 0; i < this.image.getWidth(); i++) { + for (int j = 0; j < this.image.getHeight(); j++) { + result.setRGB(i, j, image.getRGB(i, j)); + } + } + return result; + } + } diff --git a/src/net/sourceforge/plantuml/ugraphic/UPath.java b/src/net/sourceforge/plantuml/ugraphic/UPath.java index a95881d90..baf112ced 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UPath.java +++ b/src/net/sourceforge/plantuml/ugraphic/UPath.java @@ -60,6 +60,10 @@ public class UPath extends AbstractShadowable implements Iterable { addInternal(new USegment(coord, pathType)); } + public boolean isEmpty() { + return segments.size() == 0; + } + private void addInternal(USegment segment) { segments.add(segment); final double coord[] = segment.getCoord(); @@ -106,6 +110,10 @@ public class UPath extends AbstractShadowable implements Iterable { add(new double[] { x, y }, USegmentType.SEG_LINETO); } + public void cubicTo(Point2D p1, Point2D p2, Point2D p) { + cubicTo(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p.getX(), p.getY()); + } + public void cubicTo(double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2) { add(new double[] { ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2 }, USegmentType.SEG_CUBICTO); } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverDotPathEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverDotPathEps.java index e9996272c..da77586cd 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverDotPathEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverDotPathEps.java @@ -50,7 +50,7 @@ public class DriverDotPathEps implements UDriver { if (param.getColor() != null) { eps.setStrokeColor(mapper.getMappedColor(param.getColor())); - eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDashVisible(), param.getStroke() + eps.setStrokeWidth(param.getStroke().getThickness(), param.getStroke().getDashVisible(), param.getStroke() .getDashSpace()); shape.draw(eps, x, y); } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java index db5320b33..6c91db12c 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java @@ -73,7 +73,7 @@ public class DriverEllipseEps implements UDriver { eps.setFillColor(mapper.getMappedColor(param.getBackcolor())); eps.setStrokeColor(mapper.getMappedColor(param.getColor())); - eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDashVisible(), param.getStroke() + eps.setStrokeWidth(param.getStroke().getThickness(), param.getStroke().getDashVisible(), param.getStroke() .getDashSpace()); if (shape.getStart() == 0 && shape.getExtend() == 0) { diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java index 5deb1106f..200b36efd 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java @@ -65,7 +65,7 @@ public class DriverImageEps implements UDriver { } } - eps.drawImage(shape.getImage(), x, y); + eps.drawImage(shape.muteTransparentColor(mapper.getMappedColor(param.getBackcolor())).getImage(), x, y); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java index c08df483b..c8794cab2 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java @@ -72,7 +72,7 @@ public class DriverLineEps implements UDriver { } eps.setStrokeColor(mapper.getMappedColor(param.getColor())); - eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDashVisible(), param.getStroke() + eps.setStrokeWidth(param.getStroke().getThickness(), param.getStroke().getDashVisible(), param.getStroke() .getDashSpace()); eps.epsLine(x, y, x2, y2); } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverPathEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverPathEps.java index b470be997..2e55750fd 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverPathEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverPathEps.java @@ -48,7 +48,7 @@ public class DriverPathEps implements UDriver { eps.setStrokeColor(mapper.getMappedColor(param.getColor())); eps.setFillColor(mapper.getMappedColor(param.getBackcolor())); - eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDashVisible(), param + eps.setStrokeWidth(param.getStroke().getThickness(), param.getStroke().getDashVisible(), param .getStroke().getDashSpace()); eps.epsPath(x, y, shape); diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java index 2aa69782c..37ba91879 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java @@ -89,7 +89,7 @@ public class DriverRectangleEps implements UDriver { } else { eps.setStrokeColor(mapper.getMappedColor(param.getColor())); eps.setFillColor(mapper.getMappedColor(param.getBackcolor())); - eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDashVisible(), param + eps.setStrokeWidth(param.getStroke().getThickness(), param.getStroke().getDashVisible(), param .getStroke().getDashSpace()); eps.epsRectangle(x, y, width, height, rx / 2, ry / 2); } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java index db05620fd..57b420ef3 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java @@ -103,7 +103,7 @@ public class DriverTextEps implements UDriver { if (extended != null) { eps.setStrokeColor(extended); eps.setFillColor(extended); - eps.setStrokeWidth("1", 0, 0); + eps.setStrokeWidth(1, 0, 0); if (dim == null) { dim = getMinMax(x, y, getOutline(textLayout).getPathIterator(null)); } @@ -122,9 +122,9 @@ public class DriverTextEps implements UDriver { if (dim == null) { dim = getMinMax(x, y, getOutline(textLayout).getPathIterator(null)); } - eps.setStrokeWidth("1.1", 0, 0); + eps.setStrokeWidth(1.1, 0, 0); eps.epsLine(x, y + 1.5, x + dim.getWidth(), y + 1.5); - eps.setStrokeWidth("1", 0, 0); + eps.setStrokeWidth(1, 0, 0); } if (fontConfiguration.containsStyle(FontStyle.WAVE)) { if (dim == null) { @@ -135,12 +135,12 @@ public class DriverTextEps implements UDriver { if (extended != null) { eps.setStrokeColor(mapper.getMappedColor(extended)); } - eps.setStrokeWidth("1.1", 0, 0); + eps.setStrokeWidth(1.1, 0, 0); for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) { eps.epsLine(i, ypos - 0, i + 3, ypos + 1); eps.epsLine(i + 3, ypos + 1, i + 6, ypos - 0); } - eps.setStrokeWidth("1", 0, 0); + eps.setStrokeWidth(1, 0, 0); } if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { final HtmlColor extended = fontConfiguration.getExtendedColor(); @@ -152,9 +152,9 @@ public class DriverTextEps implements UDriver { } // final FontMetrics fm = font.getFontMetrics(); final double ypos = (dim.getMinY() + dim.getMaxY() * 2) / 3; - eps.setStrokeWidth("1.3", 0, 0); + eps.setStrokeWidth(1.3, 0, 0); eps.epsLine(x, ypos, x + dim.getWidth(), ypos); - eps.setStrokeWidth("1", 0, 0); + eps.setStrokeWidth(1, 0, 0); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/html5/Html5Drawer.java b/src/net/sourceforge/plantuml/ugraphic/html5/Html5Drawer.java index acff7093c..3533e1250 100644 --- a/src/net/sourceforge/plantuml/ugraphic/html5/Html5Drawer.java +++ b/src/net/sourceforge/plantuml/ugraphic/html5/Html5Drawer.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml.ugraphic.html5; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.tikz.TikzGraphics; public class Html5Drawer { @@ -58,7 +58,7 @@ public class Html5Drawer { } private static String format(double x) { - return EpsGraphics.format(x); + return TikzGraphics.format(x); } public final void setStrokeColor(String stroke) { diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteColorBuilder4096.java b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteColorBuilder4096.java index babf536c9..6048000a5 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteColorBuilder4096.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteColorBuilder4096.java @@ -45,7 +45,7 @@ public class SpriteColorBuilder4096 { private final static ColorPalette4096 COLOR_PALETTE = new ColorPalette4096(); - public static Sprite buildSprite(List strings) { + public static Sprite buildSprite(List strings) { final SpriteColor result = new SpriteColor(strings.get(0).length() / 2, strings.size()); for (int col = 0; col < result.getWidth(); col++) { for (int line = 0; line < result.getHeight(); line++) { diff --git a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteGrayLevel.java b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteGrayLevel.java index 1254265b4..6c7381cd6 100644 --- a/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteGrayLevel.java +++ b/src/net/sourceforge/plantuml/ugraphic/sprite/SpriteGrayLevel.java @@ -169,7 +169,7 @@ public enum SpriteGrayLevel { return grey / 16; } - public Sprite buildSprite(int width, int height, List strings) { + public Sprite buildSprite(int width, int height, List strings) { if (this == SpriteGrayLevel.GRAY_16) { return buildSprite16(strings); } @@ -182,7 +182,7 @@ public enum SpriteGrayLevel { throw new UnsupportedOperationException(toString()); } - private Sprite buildSprite16(List strings) { + private Sprite buildSprite16(List strings) { final SpriteMonochrome result = new SpriteMonochrome(strings.get(0).length(), strings.size(), 16); for (int col = 0; col < result.getWidth(); col++) { for (int line = 0; line < result.getHeight(); line++) { @@ -199,7 +199,7 @@ public enum SpriteGrayLevel { return result; } - private Sprite buildSprite8(int width, int height, List strings) { + private Sprite buildSprite8(int width, int height, List strings) { final SpriteMonochrome result = new SpriteMonochrome(width, height, 8); for (int col = 0; col < result.getWidth(); col++) { for (int line = 0; line < strings.size(); line++) { @@ -217,7 +217,7 @@ public enum SpriteGrayLevel { return result; } - private Sprite buildSprite4(int width, int height, List strings) { + private Sprite buildSprite4(int width, int height, List strings) { final SpriteMonochrome result = new SpriteMonochrome(width, height, 4); for (int col = 0; col < result.getWidth(); col++) { for (int line = 0; line < strings.size(); line++) { diff --git a/src/net/sourceforge/plantuml/ugraphic/tikz/DriverEllipseTikz.java b/src/net/sourceforge/plantuml/ugraphic/tikz/DriverEllipseTikz.java index 71e44ca7c..be8948ac1 100644 --- a/src/net/sourceforge/plantuml/ugraphic/tikz/DriverEllipseTikz.java +++ b/src/net/sourceforge/plantuml/ugraphic/tikz/DriverEllipseTikz.java @@ -58,13 +58,17 @@ public class DriverEllipseTikz implements UDriver { if (start == 0 && extend == 0) { tikz.ellipse(cx, cy, width / 2, height / 2); } else { - throw new UnsupportedOperationException(); + start = start + 90; + final double x1 = cx + Math.sin(start * Math.PI / 180.) * width / 2; + final double y1 = cy + Math.cos(start * Math.PI / 180.) * height / 2; + final double x2 = cx + Math.sin((start + extend) * Math.PI / 180.) * width / 2; + final double y2 = cy + Math.cos((start + extend) * Math.PI / 180.) * height / 2; + // start = start + 360; + // tikz.arc(x2, y2, (int) start, (int) (start - 45), (width + height) / 4); + + tikz.arc(x1, y1, (int) ((360-(start+270))), (int) (360-((start+270+extend))), (width + height) / 4); + // tikz.arc(x1, y1, (int) (start + 270 + extend), (int) (start + 270), (width + height) / 4); // // http://www.itk.ilstu.edu/faculty/javila/SVG/SVG_drawing1/elliptical_curve.htm - // start = start + 90; - // final double x1 = cx + Math.sin(start * Math.PI / 180.) * width / 2; - // final double y1 = cy + Math.cos(start * Math.PI / 180.) * height / 2; - // final double x2 = cx + Math.sin((start + extend) * Math.PI / 180.) * width / 2; - // final double y2 = cy + Math.cos((start + extend) * Math.PI / 180.) * height / 2; // // svg.svgEllipse(x1, y1, 1, 1, 0); // // svg.svgEllipse(x2, y2, 1, 1, 0); // svg.svgArcEllipse(width / 2, height / 2, x1, y1, x2, y2); diff --git a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java index 102017ccc..5711b0bf0 100644 --- a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java +++ b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java @@ -40,7 +40,6 @@ import java.io.OutputStream; import java.io.PrintStream; import net.sourceforge.plantuml.Dimension2DDouble; -import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.asciiart.TextStringBounder; import net.sourceforge.plantuml.asciiart.TranslatedCharArea; diff --git a/src/net/sourceforge/plantuml/ugraphic/visio/VisioGraphics.java b/src/net/sourceforge/plantuml/ugraphic/visio/VisioGraphics.java index 6e05eb10f..2ad5cefe8 100644 --- a/src/net/sourceforge/plantuml/ugraphic/visio/VisioGraphics.java +++ b/src/net/sourceforge/plantuml/ugraphic/visio/VisioGraphics.java @@ -168,7 +168,7 @@ public class VisioGraphics { } else if (type == USegmentType.SEG_CLOSE) { // Nothing } else { - Log.println("unknown " + seg); + Log.println("unknown5 " + seg); } } diff --git a/src/net/sourceforge/plantuml/utils/StartUtils.java b/src/net/sourceforge/plantuml/utils/StartUtils.java index 4854f88d0..d0d603255 100644 --- a/src/net/sourceforge/plantuml/utils/StartUtils.java +++ b/src/net/sourceforge/plantuml/utils/StartUtils.java @@ -35,7 +35,7 @@ */ package net.sourceforge.plantuml.utils; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; @@ -50,14 +50,14 @@ public class StartUtils { public static final String PAUSE_PATTERN = "(?i)((?:\\W|\\<[^<>]*\\>)*)[@\\\\]unpause"; public static final String START_PATTERN = "(?i)((?:[^\\w~]|\\<[^<>]*\\>)*)[@\\\\]start"; - public static String beforeStartUml(final CharSequence2 result) { + public static String beforeStartUml(final String s) { boolean inside = false; - for (int i = 0; i < result.length(); i++) { - final CharSequence2 tmp = result.subSequence(i, result.length()); + for (int i = 0; i < s.length(); i++) { + final String tmp = s.substring(i, s.length()); if (startsWithSymbolAnd("start", tmp)) { - return result.subSequence(0, i).toString(); + return s.substring(0, i); } - final String single = result.subSequence(i, i + 1).toString(); + final String single = s.substring(i, i + 1); if (inside) { if (single.equals(">")) { inside = false; @@ -78,7 +78,7 @@ public class StartUtils { // return null; } - public static boolean isArobaseStartDiagram(CharSequence s) { + public static boolean isArobaseStartDiagram(String s) { final String s2 = StringUtils.trinNoTrace(s); if (s2.startsWith("@") == false && s2.startsWith("\\") == false) { return false; @@ -86,33 +86,33 @@ public class StartUtils { return DiagramType.getTypeFromArobaseStart(s2) != DiagramType.UNKNOWN; } - public static boolean startsWithSymbolAnd(String value, final CharSequence2 tmp) { - return tmp.startsWith("@" + value) || tmp.startsWith("\\" + value); + public static boolean startsWithSymbolAnd(String value, final StringLocated tmp) { + return tmp.getString().startsWith("@" + value) || tmp.getString().startsWith("\\" + value); } public static boolean startsWithSymbolAnd(String value, final String tmp) { return tmp.startsWith("@" + value) || tmp.startsWith("\\" + value); } - public static boolean startOrEnd(final CharSequence2 s) { - final String s2 = StringUtils.trinNoTrace(s); + public static boolean startOrEnd(final StringLocated s) { + final String s2 = StringUtils.trinNoTrace(s.getString()); if (s2.startsWith("@") == false && s2.startsWith("\\") == false) { return false; } return startsWithSymbolAnd("end", s2) || DiagramType.getTypeFromArobaseStart(s2) != DiagramType.UNKNOWN; } - public static boolean isArobaseEndDiagram(CharSequence s) { + public static boolean isArobaseEndDiagram(String s) { final String s2 = StringUtils.trinNoTrace(s); return startsWithSymbolAnd("end", s2); } - public static boolean isArobasePauseDiagram(CharSequence s) { + public static boolean isArobasePauseDiagram(String s) { final String s2 = StringUtils.trinNoTrace(s); return startsWithSymbolAnd("pause", s2); } - public static boolean isArobaseUnpauseDiagram(CharSequence s) { + public static boolean isArobaseUnpauseDiagram(String s) { final String s2 = StringUtils.trinNoTrace(s); return startsWithSymbolAnd("unpause", s2); } @@ -124,11 +124,12 @@ public class StartUtils { private static final Pattern2 append = MyPattern.cmpile("^\\W*[@\\\\]append"); - public static CharSequence2 getPossibleAppend(CharSequence2 s) { + public static StringLocated getPossibleAppend(StringLocated cs) { + final String s = cs.getString(); final Matcher2 m = append.matcher(s); if (m.find()) { - return s.subSequence(m.group(0).length(), s.length()).trin(); - // return StringUtils.trin(s.toString().substring(m.group(0).length())); + final String tmp = s.substring(m.group(0).length(), s.length()); + return new StringLocated(StringUtils.trin(tmp), cs.getLocation(), cs.getPreprocessorError()); } return null; } diff --git a/src/net/sourceforge/plantuml/version/IteratorCounter2.java b/src/net/sourceforge/plantuml/version/IteratorCounter2.java index 4afc1e650..fe0fe6299 100644 --- a/src/net/sourceforge/plantuml/version/IteratorCounter2.java +++ b/src/net/sourceforge/plantuml/version/IteratorCounter2.java @@ -36,17 +36,17 @@ package net.sourceforge.plantuml.version; import java.util.Iterator; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; -public interface IteratorCounter2 extends Iterator { +public interface IteratorCounter2 extends Iterator { public int currentNum(); public IteratorCounter2 cloneMe(); - public CharSequence2 peek(); + public StringLocated peek(); - public CharSequence2 peekPrevious(); + public StringLocated peekPrevious(); public void copyStateFrom(IteratorCounter2 other); diff --git a/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java b/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java index 1a08b0fbc..4cedf154d 100644 --- a/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java +++ b/src/net/sourceforge/plantuml/version/IteratorCounter2Impl.java @@ -36,11 +36,11 @@ package net.sourceforge.plantuml.version; import java.util.List; -import net.sourceforge.plantuml.CharSequence2; +import net.sourceforge.plantuml.StringLocated; public class IteratorCounter2Impl implements IteratorCounter2 { - private List data; + private List data; private int nb; public void copyStateFrom(IteratorCounter2 other) { @@ -49,11 +49,11 @@ public class IteratorCounter2Impl implements IteratorCounter2 { this.data = source.data; } - public IteratorCounter2Impl(List data) { + public IteratorCounter2Impl(List data) { this(data, 0); } - private IteratorCounter2Impl(List data, int nb) { + private IteratorCounter2Impl(List data, int nb) { this.data = data; this.nb = nb; } @@ -66,15 +66,15 @@ public class IteratorCounter2Impl implements IteratorCounter2 { return nb < data.size(); } - public CharSequence2 next() { + public StringLocated next() { return data.get(nb++); } - public CharSequence2 peek() { + public StringLocated peek() { return data.get(nb); } - public CharSequence2 peekPrevious() { + public StringLocated peekPrevious() { if (nb == 0) { return null; } diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java index d094e1c17..747597d14 100644 --- a/src/net/sourceforge/plantuml/version/PSystemVersion.java +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -65,7 +65,7 @@ import net.sourceforge.plantuml.graphic.GraphicPosition; import net.sourceforge.plantuml.graphic.GraphicStrings; import net.sourceforge.plantuml.preproc.ImportedFiles; import net.sourceforge.plantuml.preproc.Stdlib; -import net.sourceforge.plantuml.preproc2.PreprocessorInclude3; +import net.sourceforge.plantuml.preproc2.PreprocessorInclude; import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ImageBuilder; @@ -182,7 +182,7 @@ public class PSystemVersion extends AbstractPSystem { strings.add("Word Mode"); strings.add("Command Line: " + Run.getCommandLine()); strings.add("Current Dir: " + new File(".").getAbsolutePath()); - strings.add("plantuml.include.path: " + PreprocessorInclude3.getenv("plantuml.include.path")); + strings.add("plantuml.include.path: " + PreprocessorInclude.getenv("plantuml.include.path")); } } strings.add(" "); diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 426224f15..fc015f4f4 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 1201902; + return 1201904; } public static int versionPatched() { @@ -88,7 +88,7 @@ public class Version { } public static long compileTime() { - return 1551475240238L; + return 1553874276192L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/wbs/CommandWBSOrgmode.java b/src/net/sourceforge/plantuml/wbs/CommandWBSOrgmode.java new file mode 100644 index 000000000..b03c3f4ac --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/CommandWBSOrgmode.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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.wbs; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +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.mindmap.IdeaShape; + +public class CommandWBSOrgmode extends SingleLineCommand2 { + + public CommandWBSOrgmode() { + super(false, getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("TYPE", "([*]+)"), // + new RegexLeaf("DIRECTION", "([<>])?"), // + new RegexLeaf("[%s]+"), // + new RegexLeaf("LABEL", "([^%s].*)"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(WBSDiagram diagram, LineLocation location, RegexResult arg) { + final String type = arg.get("TYPE", 0); + final String label = arg.get("LABEL", 0); + final String direction = arg.get("DIRECTION", 0); + final Direction dir = "<".equals(direction) ? Direction.LEFT : Direction.RIGHT; + return diagram.addIdea(type.length() - 1, label, dir, IdeaShape.BOX); + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/CommandWBSPlus.java b/src/net/sourceforge/plantuml/wbs/CommandWBSPlus.java new file mode 100644 index 000000000..ec0a4ddff --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/CommandWBSPlus.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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.wbs; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +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.mindmap.IdeaShape; + +public class CommandWBSPlus extends SingleLineCommand2 { + + public CommandWBSPlus() { + super(false, getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("TYPE", "([+-]+)"), // + new RegexLeaf("SHAPE", "(_)?"), // + new RegexLeaf("[%s]+"), // + new RegexLeaf("LABEL", "([^%s].*)"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(WBSDiagram diagram, LineLocation location, RegexResult arg) { + final String type = arg.get("TYPE", 0); + final String label = arg.get("LABEL", 0); + final Direction dir = type.contains("-") ? Direction.LEFT : Direction.RIGHT; + return diagram.addIdea(type.length() - 1, label, dir, IdeaShape.fromDesc(arg.get("SHAPE", 0))); + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/CommandWBSTabulation.java b/src/net/sourceforge/plantuml/wbs/CommandWBSTabulation.java new file mode 100644 index 000000000..2b44d1279 --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/CommandWBSTabulation.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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.wbs; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +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.mindmap.IdeaShape; + +public class CommandWBSTabulation extends SingleLineCommand2 { + + public CommandWBSTabulation() { + super(false, getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("TYPE", "([ \t]*[*+-])"), // + new RegexLeaf("SHAPE", "(_)?"), // + new RegexLeaf("[%s]+"), // + new RegexLeaf("LABEL", "([^%s].*)"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(WBSDiagram diagram, LineLocation location, RegexResult arg) { + final String type = arg.get("TYPE", 0); + final String label = arg.get("LABEL", 0); + final Direction dir = type.contains("-") ? Direction.LEFT : Direction.RIGHT; + return diagram.addIdea(type.length() - 1, label, dir, IdeaShape.fromDesc(arg.get("SHAPE", 0))); + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/Fork2.java b/src/net/sourceforge/plantuml/wbs/Fork2.java new file mode 100644 index 000000000..9a0ec1509 --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/Fork2.java @@ -0,0 +1,103 @@ +/* ======================================================================== + * 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.wbs; + +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class Fork2 extends WBSTextBlock { + + private final TextBlock main; + private final List right = new ArrayList(); + + public Fork2(ISkinParam skinParam, WElement idea) { + super(skinParam); + this.main = buildMain(idea); + for (WElement child : idea.getChildren(Direction.RIGHT)) { + this.right.add(ITFComposed.build2(skinParam, child)); + } + } + + final private double delta1x = 20; + final private double deltay = 40; + + public void drawU(final UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Dimension2D fullDim = calculateDimension(stringBounder); + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double dx = (fullDim.getWidth() - mainDim.getWidth()) / 2; + main.drawU(ug.apply(new UTranslate(dx, 0))); + drawLine(ug, dx + mainDim.getWidth() / 2, mainDim.getHeight(), dx + mainDim.getWidth() / 2, mainDim.getHeight() + + deltay / 2); + double x = 0; + final double y = mainDim.getHeight() + deltay; + final double firstX = right.get(0).getT1(stringBounder).getX(); + double lastX = firstX; + for (ITF child : right) { + lastX = x + child.getT1(stringBounder).getX(); + drawLine(ug, lastX, mainDim.getHeight() + deltay / 2, lastX, y); + child.drawU(ug.apply(new UTranslate(x, y))); + x += child.calculateDimension(stringBounder).getWidth() + delta1x; + } + lastX = Math.max(lastX, dx + mainDim.getWidth() / 2); + drawLine(ug, firstX, mainDim.getHeight() + deltay / 2, lastX, mainDim.getHeight() + deltay / 2); + + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + double width = 0; + double height = 0; + for (ITF child : right) { + final Dimension2D childDim = child.calculateDimension(stringBounder); + height = Math.max(height, childDim.getHeight()); + width += childDim.getWidth(); + } + final Dimension2D mainDim = main.calculateDimension(stringBounder); + height += mainDim.getHeight(); + width = Math.max(width, mainDim.getWidth()); + return new Dimension2DDouble(width, height); + } + +} diff --git a/src/net/sourceforge/plantuml/CharSequence2.java b/src/net/sourceforge/plantuml/wbs/ITF.java similarity index 73% rename from src/net/sourceforge/plantuml/CharSequence2.java rename to src/net/sourceforge/plantuml/wbs/ITF.java index 3f077c0c0..3d4b2023b 100644 --- a/src/net/sourceforge/plantuml/CharSequence2.java +++ b/src/net/sourceforge/plantuml/wbs/ITF.java @@ -33,27 +33,21 @@ * * */ -package net.sourceforge.plantuml; +package net.sourceforge.plantuml.wbs; -public interface CharSequence2 extends CharSequence { +import java.awt.geom.Point2D; - public int length(); +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; - public char charAt(int index); +public interface ITF extends TextBlock { - public CharSequence2 subSequence(int start, int end); + public Point2D getT1(StringBounder stringBounder); - public String toString2(); + public Point2D getT2(StringBounder stringBounder); - public LineLocation getLocation(); - - public CharSequence2 trin(); - - public boolean startsWith(String string); - - public String getPreprocessorError(); - - public CharSequence2 withErrorPreprocessor(String preprocessorError); + public Point2D getF1(StringBounder stringBounder); + public Point2D getF2(StringBounder stringBounder); } diff --git a/src/net/sourceforge/plantuml/wbs/ITFComposed.java b/src/net/sourceforge/plantuml/wbs/ITFComposed.java new file mode 100644 index 000000000..179fc7fe8 --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/ITFComposed.java @@ -0,0 +1,175 @@ +/* ======================================================================== + * 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.wbs; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class ITFComposed extends WBSTextBlock implements ITF { + + private final List left; + private final List right; + + private final TextBlock main; + + final private double delta1x = 10; + final private double deltay = 15; + + private ITFComposed(ISkinParam skinParam, WElement idea, List left, List right) { + super(skinParam); + this.left = left; + this.right = right; + this.main = buildMain(idea); + } + + public static ITF build2(ISkinParam skinParam, WElement idea) { + if (idea.isLeaf()) { + return new ITFLeaf(skinParam, idea.getLabel(), idea.getShape()); + } + final List left = new ArrayList(); + final List right = new ArrayList(); + for (WElement child : idea.getChildren(Direction.LEFT)) { + left.add(build2(skinParam, child)); + } + for (WElement child : idea.getChildren(Direction.RIGHT)) { + right.add(build2(skinParam, child)); + } + return new ITFComposed(skinParam, idea, left, right); + } + + final protected double getw1(StringBounder stringBounder) { + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double mainWidth = mainDim.getWidth(); + return Math.max(mainWidth / 2, delta1x + getCollWidth(stringBounder, left)); + } + + final public Point2D getT1(StringBounder stringBounder) { + final double x = getw1(stringBounder); + final double y = 0; + return new Point2D.Double(x, y); + } + + final public Point2D getT2(StringBounder stringBounder) { + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double x = getw1(stringBounder); + final double y = mainDim.getHeight(); + return new Point2D.Double(x, y); + } + + final public Point2D getF1(StringBounder stringBounder) { + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double x = getw1(stringBounder) - mainDim.getWidth() / 2; + final double y = mainDim.getHeight() / 2; + return new Point2D.Double(x, y); + } + + final public Point2D getF2(StringBounder stringBounder) { + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double x = getw1(stringBounder) + mainDim.getWidth() / 2; + final double y = mainDim.getHeight() / 2; + return new Point2D.Double(x, y); + } + + public final Dimension2D calculateDimension(StringBounder stringBounder) { + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double mainWidth = mainDim.getWidth(); + final double height = mainDim.getHeight() + + Math.max(getCollHeight(stringBounder, left, deltay), getCollHeight(stringBounder, right, deltay)); + final double width = Math.max(mainWidth / 2, delta1x + getCollWidth(stringBounder, left)) + + Math.max(mainWidth / 2, delta1x + getCollWidth(stringBounder, right)); + return new Dimension2DDouble(width, height); + } + + public void drawU(final UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Dimension2D mainDim = main.calculateDimension(stringBounder); + final double wx = getw1(stringBounder) - mainDim.getWidth() / 2; + main.drawU(ug.apply(new UTranslate(wx, 0))); + final double x = getw1(stringBounder); + double y = mainDim.getHeight(); + double lastY1 = y; + for (ITF child : left) { + y += deltay; + final Dimension2D childDim = child.calculateDimension(stringBounder); + lastY1 = y + child.getF2(stringBounder).getY(); + drawLine(ug, x - childDim.getWidth() - delta1x + child.getF2(stringBounder).getX(), lastY1, x, lastY1); + child.drawU(ug.apply(new UTranslate(x - childDim.getWidth() - delta1x, y))); + y += childDim.getHeight(); + } + + y = mainDim.getHeight(); + double lastY2 = y; + for (ITF child : right) { + y += deltay; + final Dimension2D childDim = child.calculateDimension(stringBounder); + lastY2 = y + child.getF1(stringBounder).getY(); + drawLine(ug, x, lastY2, x + delta1x + child.getF1(stringBounder).getX(), lastY2); + child.drawU(ug.apply(new UTranslate(x + delta1x, y))); + y += childDim.getHeight(); + + } + drawLine(ug, x, mainDim.getHeight(), x, Math.max(lastY1, lastY2)); + } + + + final private double getCollWidth(StringBounder stringBounder, Collection all) { + double result = 0; + for (TextBlock child : all) { + result = Math.max(result, child.calculateDimension(stringBounder).getWidth()); + } + return result; + } + + final private double getCollHeight(StringBounder stringBounder, Collection all, double deltay) { + double result = 0; + for (TextBlock child : all) { + result += deltay + child.calculateDimension(stringBounder).getHeight(); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/ITFLeaf.java b/src/net/sourceforge/plantuml/wbs/ITFLeaf.java new file mode 100644 index 000000000..045335957 --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/ITFLeaf.java @@ -0,0 +1,103 @@ +/* ======================================================================== + * 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.wbs; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; +import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileBox; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.color.Colors; +import net.sourceforge.plantuml.mindmap.IdeaShape; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ITFLeaf extends AbstractTextBlock implements ITF { + + private final ISkinParam skinParam; + private final TextBlock box; + + public ITFLeaf(ISkinParam skinParam, Display label, IdeaShape shape) { + this.skinParam = skinParam; + final UFont font = skinParam.getFont(null, false, FontParam.ACTIVITY); + + if (shape == IdeaShape.BOX) { + this.box = new FtileBox(Colors.empty().mute(skinParam), label, font, null, BoxStyle.SDL_TASK); + } else { + final TextBlock text = label.create(FontConfiguration.blackBlueTrue(font), HorizontalAlignment.LEFT, + skinParam); + this.box = TextBlockUtils.withMargin(text, 0, 3, 1, 1); + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return box.calculateDimension(stringBounder); + } + + public void drawU(UGraphic ug) { + box.drawU(ug); + } + + public Point2D getT1(StringBounder stringBounder) { + final Dimension2D dim = calculateDimension(stringBounder); + return new Point2D.Double(dim.getWidth() / 2, 0); + } + + public Point2D getT2(StringBounder stringBounder) { + final Dimension2D dim = calculateDimension(stringBounder); + return new Point2D.Double(dim.getWidth() / 2, dim.getHeight()); + } + + public Point2D getF1(StringBounder stringBounder) { + final Dimension2D dim = calculateDimension(stringBounder); + return new Point2D.Double(0, dim.getHeight() / 2); + } + + public Point2D getF2(StringBounder stringBounder) { + final Dimension2D dim = calculateDimension(stringBounder); + return new Point2D.Double(dim.getWidth(), dim.getHeight() / 2); + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/WBSDiagram.java b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java new file mode 100644 index 000000000..42870ef33 --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java @@ -0,0 +1,170 @@ +/* ======================================================================== + * 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.wbs; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.OutputStream; + +import net.sourceforge.plantuml.AnnotatedWorker; +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.Scale; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.core.DiagramDescription; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.mindmap.IdeaShape; +import net.sourceforge.plantuml.svek.TextBlockBackcolored; +import net.sourceforge.plantuml.ugraphic.ImageBuilder; +import net.sourceforge.plantuml.ugraphic.MinMax; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class WBSDiagram extends UmlDiagram { + + public DiagramDescription getDescription() { + return new DiagramDescription("Work Breakdown Structure"); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.WBS; + } + + @Override + protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption) + throws IOException { + final Scale scale = getScale(); + + final double dpiFactor = scale == null ? 1 : scale.getScale(100, 100); + final ISkinParam skinParam = getSkinParam(); + final ImageBuilder imageBuilder = new ImageBuilder(skinParam.getColorMapper(), dpiFactor, + skinParam.getBackgroundColor(), "", "", 10, 10, null, skinParam.handwritten()); + TextBlock result = getTextBlock(); + + result = new AnnotatedWorker(this, skinParam, fileFormatOption.getDefaultStringBounder()).addAdd(result); + imageBuilder.setUDrawable(result); + + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed(), os); + } + + private TextBlockBackcolored getTextBlock() { + return new TextBlockBackcolored() { + + public void drawU(UGraphic ug) { + drawMe(ug); + } + + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return null; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return getDrawingElement().calculateDimension(stringBounder); + + } + + public MinMax getMinMax(StringBounder stringBounder) { + throw new UnsupportedOperationException(); + } + + public HtmlColor getBackcolor() { + return null; + } + }; + } + + private void drawMe(UGraphic ug) { + getDrawingElement().drawU(ug); + + } + + private TextBlock getDrawingElement() { + return new Fork2(getSkinParam(), root); + } + + public CommandExecutionResult addIdea(int level, String label, Direction direction, IdeaShape shape) { + if (level == 0) { + if (root != null) { + return CommandExecutionResult.error("Error 44"); + } + initRoot(label); + return CommandExecutionResult.ok(); + } + return add(level, label, direction, shape); + } + + private WElement root; + private WElement last; + + private void initRoot(String label) { + root = new WElement(Display.getWithNewlines(label)); + last = root; + } + + private WElement getParentOfLast(int nb) { + WElement result = last; + for (int i = 0; i < nb; i++) { + result = result.getParent(); + } + return result; + } + + private CommandExecutionResult add(int level, String label, Direction direction, IdeaShape shape) { + if (level == last.getLevel() + 1) { + final WElement newIdea = last.createElement(level, Display.getWithNewlines(label), direction, shape); + last = newIdea; + return CommandExecutionResult.ok(); + } + if (level <= last.getLevel()) { + final int diff = last.getLevel() - level + 1; + final WElement newIdea = getParentOfLast(diff).createElement(level, Display.getWithNewlines(label), + direction, shape); + last = newIdea; + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("error42L"); + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java b/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java new file mode 100644 index 000000000..5c2581a5b --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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.wbs; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.UmlDiagramFactory; +import net.sourceforge.plantuml.core.DiagramType; + +public class WBSDiagramFactory extends UmlDiagramFactory { + + public WBSDiagramFactory() { + super(DiagramType.WBS); + } + + @Override + protected List createCommands() { + + final List cmds = new ArrayList(); + addCommonCommands(cmds); + cmds.add(new CommandWBSOrgmode()); + cmds.add(new CommandWBSPlus()); + cmds.add(new CommandWBSTabulation()); + + return cmds; + } + + @Override + public WBSDiagram createEmptyDiagram() { + return new WBSDiagram(); + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/WBSTextBlock.java b/src/net/sourceforge/plantuml/wbs/WBSTextBlock.java new file mode 100644 index 000000000..3001a460b --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/WBSTextBlock.java @@ -0,0 +1,99 @@ +/* ======================================================================== + * 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.wbs; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle; +import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileBox; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.color.Colors; +import net.sourceforge.plantuml.mindmap.IdeaShape; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public abstract class WBSTextBlock extends AbstractTextBlock { + + protected final ISkinParam skinParam; + + public WBSTextBlock(ISkinParam skinParam) { + this.skinParam = skinParam; + } + + final protected HtmlColor getLinkColor() { + return ColorParam.activityBorder.getDefaultValue(); + } + + final protected void drawLine(UGraphic ug, Point2D p1, Point2D p2) { + final ULine line = new ULine(p1, p2); + ug.apply(new UTranslate(p1)).apply(new UChangeColor(getLinkColor())).draw(line); + } + + final protected void drawLine(UGraphic ug, double x1, double y1, double x2, double y2) { + drawLine(ug, new Point2D.Double(x1, y1), new Point2D.Double(x2, y2)); + } + + final protected TextBlock buildMain(WElement idea) { + Display label = idea.getLabel(); + final UFont font = skinParam.getFont(null, false, FontParam.ACTIVITY); + + if (idea.getShape() == IdeaShape.BOX) { + final FtileBox box = new FtileBox(Colors.empty().mute(skinParam), label, font, null, BoxStyle.SDL_TASK); + return box; + } + + final TextBlock text = label.create(FontConfiguration.blackBlueTrue(font), HorizontalAlignment.LEFT, skinParam); + // if (direction == Direction.RIGHT) { + // return TextBlockUtils.withMargin(text, 3, 0, 1, 1); + // } + return TextBlockUtils.withMargin(text, 0, 3, 1, 1); + } + + + +} diff --git a/src/net/sourceforge/plantuml/wbs/WElement.java b/src/net/sourceforge/plantuml/wbs/WElement.java new file mode 100644 index 000000000..0933a0f51 --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/WElement.java @@ -0,0 +1,109 @@ +/* ======================================================================== + * 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.wbs; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.mindmap.IdeaShape; + +class WElement { + + private final Display label; + private final int level; + private final WElement parent; + private final List childrenLeft = new ArrayList(); + private final List childrenRight = new ArrayList(); + private final IdeaShape shape; + + public WElement(Display label) { + this(label, 0, null, IdeaShape.BOX); + } + + private WElement(Display label, int level, WElement parent, IdeaShape shape) { + this.label = label; + this.level = level; + this.parent = parent; + this.shape = shape; + } + + public boolean isLeaf() { + return childrenLeft.size() == 0 && childrenRight.size() == 0; + } + + public WElement createElement(int newLevel, Display newLabel, Direction direction, IdeaShape shape) { + final WElement result = new WElement(newLabel, newLevel, this, shape); + if (direction == Direction.LEFT) { + this.childrenLeft.add(result); + } else { + this.childrenRight.add(result); + } + return result; + } + + @Override + public String toString() { + return label.toString(); + } + + public final int getLevel() { + return level; + } + + public final Display getLabel() { + return label; + } + + public Collection getChildren(Direction direction) { + if (direction == Direction.LEFT) { + return Collections.unmodifiableList(childrenLeft); + } + return Collections.unmodifiableList(childrenRight); + } + + public WElement getParent() { + return parent; + } + + public final IdeaShape getShape() { + return shape; + } + +} diff --git a/stdlib/cloudogu-abx.repx b/stdlib/cloudogu-abx.repx index 7bf0221c1..d65355036 100644 Binary files a/stdlib/cloudogu-abx.repx and b/stdlib/cloudogu-abx.repx differ