diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java index 19b96a7fe..3b0b94219 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -55,6 +55,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.stats.StatsUtils; +import net.sourceforge.plantuml.ugraphic.color.ColorMapper; @HaxeIgnored public class Option { @@ -162,6 +163,8 @@ public class Option { setFileFormatOption(new FileFormatOption(FileFormat.BASE64)); } else if (s.equalsIgnoreCase("-pdf") || s.equalsIgnoreCase("-tpdf")) { setFileFormatOption(new FileFormatOption(FileFormat.PDF)); + } else if (s.equalsIgnoreCase("-darkmode")) { + setFileFormatOption(this.fileFormatOption.withColorMapper(ColorMapper.FORCE_DARK)); } else if (s.equalsIgnoreCase("-overwrite")) { OptionFlags.getInstance().setOverwrite(true); } else if (s.equalsIgnoreCase("-output") || s.equalsIgnoreCase("-o")) { diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java index 10f6ae1f8..1d6a8195a 100644 --- a/src/net/sourceforge/plantuml/OptionPrint.java +++ b/src/net/sourceforge/plantuml/OptionPrint.java @@ -85,6 +85,7 @@ public class OptionPrint { System.out.println("\t**\tmeans any characters (used to recurse through directories)"); System.out.println(); System.out.println("where options include:"); + System.out.println(" -darkmode\t\tTo use dark mode for diagrams"); System.out.println(" -gui\t\tTo run the graphical user interface"); System.out.println(" -tpng\t\tTo generate images using PNG format (default)"); System.out.println(" -tsvg\t\tTo generate images using SVG format"); diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 1bebc881d..15fab4dd5 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -59,6 +59,7 @@ import net.sourceforge.plantuml.directdot.PSystemDotFactory; import net.sourceforge.plantuml.ditaa.PSystemDitaaFactory; import net.sourceforge.plantuml.donors.PSystemDonorsFactory; import net.sourceforge.plantuml.donors.PSystemSkinparameterListFactory; +import net.sourceforge.plantuml.ebnf.PSystemEbnfFactory; import net.sourceforge.plantuml.eggs.PSystemAppleTwoFactory; import net.sourceforge.plantuml.eggs.PSystemCharlieFactory; import net.sourceforge.plantuml.eggs.PSystemColorsFactory; @@ -106,7 +107,8 @@ public class PSystemBuilder { public static final long startTime = System.currentTimeMillis(); - final public Diagram createPSystem(List source, List rawSource, Map skinParam) { + final public Diagram createPSystem(List source, List rawSource, + Map skinParam) { final long now = System.currentTimeMillis(); @@ -224,6 +226,7 @@ public class PSystemBuilder { factories.add(new BoardDiagramFactory()); factories.add(new YamlDiagramFactory()); factories.add(new HclDiagramFactory()); + factories.add(new PSystemEbnfFactory()); } private boolean isOk(Diagram ps) { diff --git a/src/net/sourceforge/plantuml/StringLocated.java b/src/net/sourceforge/plantuml/StringLocated.java index e264ca48a..d505e1855 100644 --- a/src/net/sourceforge/plantuml/StringLocated.java +++ b/src/net/sourceforge/plantuml/StringLocated.java @@ -100,10 +100,6 @@ final public class StringLocated { return trimmed; } -// public StringLocated getTrimmedRight() { -// return new StringLocated(StringUtils.trinEnding(this.getString()), location, preprocessorError); -// } - public StringLocated removeInnerComment() { final String string = s.toString(); final String trim = string.replace('\t', ' ').trim(); diff --git a/src/net/sourceforge/plantuml/TitledDiagram.java b/src/net/sourceforge/plantuml/TitledDiagram.java index a644d661d..4e8017685 100644 --- a/src/net/sourceforge/plantuml/TitledDiagram.java +++ b/src/net/sourceforge/plantuml/TitledDiagram.java @@ -291,14 +291,14 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram, if ("reverse".equals(monochrome)) return ColorMapper.MONOCHROME_REVERSE; - final String value = getSkinParam().getValue("reversecolor"); - if (value == null) + final String reversecolor = getSkinParam().getValue("reversecolor"); + if (reversecolor == null) return init; - if ("dark".equalsIgnoreCase(value)) + if ("dark".equalsIgnoreCase(reversecolor)) return ColorMapper.LIGTHNESS_INVERSE; - final ColorOrder order = ColorOrder.fromString(value); + final ColorOrder order = ColorOrder.fromString(reversecolor); if (order == null) return init; diff --git a/src/net/sourceforge/plantuml/UmlDiagramType.java b/src/net/sourceforge/plantuml/UmlDiagramType.java index a2a4d41e0..ff77b4ea5 100644 --- a/src/net/sourceforge/plantuml/UmlDiagramType.java +++ b/src/net/sourceforge/plantuml/UmlDiagramType.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.style.SName; public enum UmlDiagramType { SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, WIRE, - HELP, GANTT, SALT, JSON, GIT, BOARD, YAML, HCL; + HELP, GANTT, SALT, JSON, GIT, BOARD, YAML, HCL, EBNF; public SName getStyleName() { if (this == SEQUENCE) { diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java index 89581d73e..8dc4687ac 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -76,7 +77,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandLinkLongActivity extends CommandMultilines2 { public CommandLinkLongActivity() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java index 9fa7f9a9c..2896bd86a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java @@ -41,6 +41,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -53,7 +54,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandActivityLong3 extends CommandMultilines2 { public CommandActivityLong3() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.LEFT_ONLY); } @Override diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java index c2d02ea03..b0cd0ab57 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -54,7 +55,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandArrowLong3 extends CommandMultilines2 { public CommandArrowLong3() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackwardLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackwardLong3.java index 1786f0d8f..52e129874 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackwardLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandBackwardLong3.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -53,7 +54,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandBackwardLong3 extends CommandMultilines2 { public CommandBackwardLong3() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java index c1b9f3275..7d52453e9 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java @@ -40,6 +40,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -55,7 +56,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandNoteLong3 extends CommandMultilines2 { public CommandNoteLong3() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } private static ColorParser color() { diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index c17db60de..b4918d0a9 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -46,6 +46,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -82,7 +83,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2 createMultiLine(boolean withBracket) { - return new CommandMultilines2(getRegexConcatMultiLine(), MultilinesStrategy.REMOVE_STARTING_QUOTE) { + return new CommandMultilines2(getRegexConcatMultiLine(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines2.java b/src/net/sourceforge/plantuml/command/CommandMultilines2.java index 0e56f5bb4..805d0c2eb 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilines2.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilines2.java @@ -46,14 +46,17 @@ public abstract class CommandMultilines2 implements Command implements Command { public CommandMultilinesLegend() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } private static IRegex getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/command/CommandSpriteSvgMultiline.java b/src/net/sourceforge/plantuml/command/CommandSpriteSvgMultiline.java index a5a46ccf2..95ad1ba19 100644 --- a/src/net/sourceforge/plantuml/command/CommandSpriteSvgMultiline.java +++ b/src/net/sourceforge/plantuml/command/CommandSpriteSvgMultiline.java @@ -47,7 +47,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandSpriteSvgMultiline extends CommandMultilines2 { public CommandSpriteSvgMultiline() { - super(getRegexConcat(), MultilinesStrategy.KEEP_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH); } private static IRegex getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/command/Trim.java b/src/net/sourceforge/plantuml/command/Trim.java new file mode 100644 index 000000000..8333a8329 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/Trim.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.command; + +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.StringLocated; + +public enum Trim { + BOTH, LEFT_ONLY; + + private String ltrim(final String tmp1) { + return LTRIM.matcher(tmp1).replaceAll(""); + } + + public String trim(StringLocated s) { + if (this == BOTH) + return s.getTrimmed().getString(); + return ltrim(s.getString()); + } + + private static Pattern LTRIM = Pattern.compile("^\\s+"); + private static Pattern RTRIM = Pattern.compile("\\s+$"); + +} diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java index 1f35678e7..a99e0e690 100644 --- a/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java @@ -44,6 +44,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -109,7 +110,7 @@ public final class CommandFactoryNote implements SingleMultiFactoryCommand createMultiLine(boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java index 6d6301952..23481b2a8 100644 --- a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java @@ -48,6 +48,7 @@ import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -92,7 +93,7 @@ public final class CommandFactoryNoteActivity implements SingleMultiFactoryComma public Command createMultiLine(boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java index cae28b022..3a5623e06 100644 --- a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -173,7 +174,7 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma public Command createMultiLine(final boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(partialPattern, withBracket), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java index 4279c8605..df3e149d0 100644 --- a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -96,7 +97,7 @@ public final class CommandFactoryNoteOnLink implements SingleMultiFactoryCommand } public Command createMultiLine(boolean withBracket) { - return new CommandMultilines2(getRegexConcatMultiLine(), MultilinesStrategy.KEEP_STARTING_QUOTE) { + return new CommandMultilines2(getRegexConcatMultiLine(), MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java index 6e692726c..3f085f665 100644 --- a/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java @@ -46,6 +46,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.Position; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -112,7 +113,7 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman public Command createMultiLine(final boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(partialPattern, withBracket), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java index 639ce76b9..2ada24ca9 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java @@ -46,6 +46,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.note.SingleMultiFactoryCommand; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -119,7 +120,7 @@ public final class FactorySequenceNoteAcrossCommand implements SingleMultiFactor public Command createMultiLine(boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java index 1e3ff6b58..e259813a5 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.note.SingleMultiFactoryCommand; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -112,7 +113,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma public Command createMultiLine(boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java index 5e52f50c9..cc9fcfc0d 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.note.SingleMultiFactoryCommand; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -115,7 +116,7 @@ public final class FactorySequenceNoteOnArrowCommand implements SingleMultiFacto public Command createMultiLine(boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java index b220f98ec..c4239d52f 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.note.SingleMultiFactoryCommand; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -134,7 +135,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF public Command createMultiLine(boolean withBracket) { return new CommandMultilines2(getRegexConcatMultiLine(), - MultilinesStrategy.KEEP_STARTING_QUOTE) { + MultilinesStrategy.KEEP_STARTING_QUOTE, Trim.BOTH) { @Override public String getPatternEnd() { diff --git a/src/net/sourceforge/plantuml/core/DiagramType.java b/src/net/sourceforge/plantuml/core/DiagramType.java index 2f712a3bb..d9c7d7640 100644 --- a/src/net/sourceforge/plantuml/core/DiagramType.java +++ b/src/net/sourceforge/plantuml/core/DiagramType.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.utils.StartUtils; public enum DiagramType { UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, NW, - MINDMAP, WBS, WIRE, JSON, GIT, BOARD, YAML, HCL, UNKNOWN; + MINDMAP, WBS, WIRE, JSON, GIT, BOARD, YAML, HCL, EBNF, UNKNOWN; static public DiagramType getTypeFromArobaseStart(String s) { s = s.toLowerCase(); @@ -118,6 +118,9 @@ public enum DiagramType { if (StartUtils.startsWithSymbolAnd("starthcl", s)) return HCL; + if (StartUtils.startsWithSymbolAnd("startebnf", s)) + return EBNF; + return UNKNOWN; } } diff --git a/src/net/sourceforge/plantuml/creole/Parser.java b/src/net/sourceforge/plantuml/creole/Parser.java index e74f0231f..04c4f50ad 100644 --- a/src/net/sourceforge/plantuml/creole/Parser.java +++ b/src/net/sourceforge/plantuml/creole/Parser.java @@ -58,6 +58,14 @@ public class Parser { return new CreoleParser(fontConfiguration, horizontalAlignment, skinParam, creoleMode, stereotype); } + public static boolean isLatexStart(String line) { + return line.equals(""); + } + + public static boolean isLatexEnd(String line) { + return line.equals(""); + } + public static boolean isCodeStart(String line) { return line.equals(""); } diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java index cbd503e99..c97beb801 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java @@ -60,17 +60,17 @@ public class CommandCreoleLatex implements Command { public int matchingSize(String line) { final Matcher2 m = pattern.matcher(line); - if (m.find() == false) { + if (m.find() == false) return 0; - } + return m.group(1).length(); } public String executeAndGetRemaining(String line, StripeSimple stripe) { final Matcher2 m = pattern.matcher(line); - if (m.find() == false) { + if (m.find() == false) throw new IllegalStateException(); - } + final String latex = m.group(2); stripe.addMath(ScientificEquationSafe.fromLatex(latex)); return line.substring(m.group(1).length()); diff --git a/src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java b/src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java index 9f055487e..1fedae4ce 100644 --- a/src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java +++ b/src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java @@ -77,8 +77,8 @@ public class CreoleParser implements SheetBuilder { private Stripe createStripe(String line, CreoleContext context, Stripe lastStripe, FontConfiguration fontConfiguration) { - if (lastStripe instanceof StripeCode) { - final StripeCode code = (StripeCode) lastStripe; + if (lastStripe instanceof StripeRaw) { + final StripeRaw code = (StripeRaw) lastStripe; if (code.isTerminated()) { lastStripe = null; } else { @@ -100,7 +100,9 @@ public class CreoleParser implements SheetBuilder { } else if (Parser.isTreeStart(line)) { return new StripeTree(fontConfiguration, skinParam, line); } else if (Parser.isCodeStart(line)) { - return new StripeCode(fontConfiguration.changeFamily(Parser.MONOSPACED), skinParam, line); + return new StripeCode(fontConfiguration.changeFamily(Parser.MONOSPACED)); + } else if (Parser.isLatexStart(line)) { + return new StripeLatex(fontConfiguration); } return new CreoleStripeSimpleParser(line, context, fontConfiguration, skinParam, creoleMode) .createStripe(context); diff --git a/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java b/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java index 64d0085fc..2521822d2 100644 --- a/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java @@ -40,10 +40,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.awt.geom.XDimension2D; import net.sourceforge.plantuml.creole.Parser; -import net.sourceforge.plantuml.creole.Stripe; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.StringBounder; @@ -51,15 +49,14 @@ import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UText; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class StripeCode implements Stripe, Atom { +public class StripeCode implements StripeRaw { final private FontConfiguration fontConfiguration; private final List raw = new ArrayList<>(); private boolean terminated; - public StripeCode(FontConfiguration fontConfiguration, ISkinSimple skinParam, String line) { -// this.skinParam = skinParam; + public StripeCode(FontConfiguration fontConfiguration) { this.fontConfiguration = fontConfiguration; } @@ -71,6 +68,7 @@ public class StripeCode implements Stripe, Atom { return null; } + @Override public boolean addAndCheckTermination(String line) { if (Parser.isCodeEnd(line)) { this.terminated = true; @@ -80,6 +78,7 @@ public class StripeCode implements Stripe, Atom { return false; } + @Override public final boolean isTerminated() { return terminated; } diff --git a/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java b/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java new file mode 100644 index 000000000..8782181f2 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java @@ -0,0 +1,111 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole.legacy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.awt.geom.XDimension2D; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.atom.Atom; +import net.sourceforge.plantuml.creole.atom.AtomMath; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.math.ScientificEquationSafe; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class StripeLatex implements StripeRaw { + + final private FontConfiguration fontConfiguration; + final private StringBuilder formula = new StringBuilder(); + private AtomMath atom; + + private boolean terminated; + + public StripeLatex(FontConfiguration fontConfiguration) { + this.fontConfiguration = fontConfiguration; + } + + public List getAtoms() { + return Collections.singletonList(this); + } + + public Atom getLHeader() { + return null; + } + + @Override + public boolean addAndCheckTermination(String line) { + if (Parser.isLatexEnd(line)) { + this.terminated = true; + return true; + } + this.formula.append(line); + return false; + } + + @Override + public final boolean isTerminated() { + return terminated; + } + + private Atom getAtom() { + if (atom == null) { + final ScientificEquationSafe math = ScientificEquationSafe.fromLatex(formula.toString()); + atom = new AtomMath(math, fontConfiguration.getColor(), fontConfiguration.getExtendedColor()); + } + return atom; + } + + public XDimension2D calculateDimension(StringBounder stringBounder) { + return getAtom().calculateDimension(stringBounder); + } + + public double getStartingAltitude(StringBounder stringBounder) { + return 0; + } + + public void drawU(UGraphic ug) { + getAtom().drawU(ug); + } + + public List splitInTwo(StringBounder stringBounder, double width) { + return Arrays.asList((Atom) this); + } + +} diff --git a/src/net/sourceforge/plantuml/creole/legacy/StripeRaw.java b/src/net/sourceforge/plantuml/creole/legacy/StripeRaw.java new file mode 100644 index 000000000..155ee0f59 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeRaw.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole.legacy; + +import net.sourceforge.plantuml.creole.Stripe; +import net.sourceforge.plantuml.creole.atom.Atom; + +public interface StripeRaw extends Stripe, Atom { + + public boolean addAndCheckTermination(String line); + + public boolean isTerminated(); + +} diff --git a/src/net/sourceforge/plantuml/creole/legacy/StripeTable.java b/src/net/sourceforge/plantuml/creole/legacy/StripeTable.java index 6654e9712..a77f67e95 100644 --- a/src/net/sourceforge/plantuml/creole/legacy/StripeTable.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeTable.java @@ -73,9 +73,9 @@ public class StripeTable implements Stripe { this.skinParam = skinParam; this.fontConfiguration = fontConfiguration; HColor lineColor = getBackOrFrontColor(line, 1); - if (lineColor == null) { + if (lineColor == null) lineColor = fontConfiguration.getColor(); - } + this.table = new AtomTable(lineColor); this.marged = new AtomWithMargin(table, 2, 2); analyzeAndAddInternal(line); @@ -91,9 +91,9 @@ public class StripeTable implements Stripe { static Atom asAtom(List cells, double padding) { final Sheet sheet = new Sheet(HorizontalAlignment.LEFT); - for (StripeSimple cell : cells) { + for (StripeSimple cell : cells) sheet.add(cell); - } + return new SheetBlock1(sheet, LineBreakStrategy.NONE, padding); } @@ -101,9 +101,9 @@ public class StripeTable implements Stripe { if (CreoleParser.doesStartByColor(line)) { final int idx1 = line.indexOf('#'); final int idx2 = line.indexOf('>'); - if (idx2 == -1) { + if (idx2 == -1) throw new IllegalStateException(); - } + final String[] color = line.substring(idx1, idx2).split(","); if (idx < color.length) { final String s = color[idx]; @@ -115,9 +115,9 @@ public class StripeTable implements Stripe { private String withouBackColor(String line) { final int idx2 = line.indexOf('>'); - if (idx2 == -1) { + if (idx2 == -1) throw new IllegalStateException(); - } + return line.substring(idx2 + 1); } @@ -126,9 +126,9 @@ public class StripeTable implements Stripe { private void analyzeAndAddInternal(String line) { line = line.replace("\\|", hiddenBar); HColor lineBackColor = getBackOrFrontColor(line, 0); - if (lineBackColor != null) { + if (lineBackColor != null) line = withouBackColor(line); - } + table.newLine(lineBackColor); for (final StringTokenizer st = new StringTokenizer(line, "|"); st.hasMoreTokens();) { Mode mode = Mode.NORMAL; @@ -138,9 +138,9 @@ public class StripeTable implements Stripe { mode = Mode.HEADER; } HColor cellBackColor = getBackOrFrontColor(v, 0); - if (cellBackColor != null) { + if (cellBackColor != null) v = withouBackColor(v); - } + final List lines = getWithNewlinesInternal(v); final List cells = new ArrayList<>(); for (String s : lines) { @@ -186,9 +186,9 @@ public class StripeTable implements Stripe { } private FontConfiguration getFontConfiguration(Mode mode) { - if (mode == Mode.NORMAL) { + if (mode == Mode.NORMAL) return fontConfiguration; - } + return fontConfiguration.bold(); } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java index 21ea42a27..b78cdb601 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java @@ -43,6 +43,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -63,7 +64,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandArchimateMultilines extends CommandMultilines2 { public CommandArchimateMultilines() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java index 06eef0b07..9f869c710 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -73,23 +74,23 @@ public class CommandCreateElementMultilines extends CommandMultilines2 values = new ArrayList<>(); + private final StyleBuilder styleBuilder; + private final HColorSet colorSet; + + public Alternation(ISkinParam skinParam) { + this.styleBuilder = skinParam.getCurrentStyleBuilder(); + this.colorSet = skinParam.getIHtmlColorSet(); + } + + public void alternation(Token token) { + values.add(0, token.getData()); + } + + @Override + public double linePos(StringBounder stringBounder) { + final Style style = getStyleSignature().getMergedStyle(styleBuilder); + final FontConfiguration fc = style.getFontConfiguration(colorSet); + final ETile tile = new ETileBox(values.get(0), fc); + return tile.linePos(stringBounder); + } + + @Override + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + ug = ug.apply(HColors.BLACK); + final Style style = getStyleSignature().getMergedStyle(styleBuilder); + final FontConfiguration fc = style.getFontConfiguration(colorSet); + double y = 0; + double lastLinePos = 0; + + final double b = 30 - 16; + final double a = b - 8; + final double c = b + 8; + + final XDimension2D fullDim = calculateDimension(stringBounder); + + final double q = fullDim.getWidth() - 14; + final double p = q - 8; + final double r = q + 8; + + for (int i = 0; i < values.size(); i++) { + final String value = values.get(i); + final ETile tile = new ETileBox(value, fc); + final XDimension2D dim = tile.calculateDimension(stringBounder); + lastLinePos = y + tile.linePos(stringBounder); + tile.drawU(ug.apply(new UTranslate(30, y))); + + if (i == 0) { + drawHline(ug, lastLinePos, 0, 30); + drawHline(ug, lastLinePos, 30 + dim.getWidth(), fullDim.getWidth()); + } else if (i > 0 && i < values.size() - 1) { + drawHline(ug, lastLinePos, c, 30); + new CornerCurved(8).drawU(ug.apply(new UTranslate(b, lastLinePos))); + drawHline(ug, lastLinePos, 30 + dim.getWidth(), p); + new CornerCurved(-8).drawU(ug.apply(new UTranslate(q, lastLinePos))); + + } else if (i == values.size() - 1) { + drawHline(ug, lastLinePos, c, 30); + drawHline(ug, lastLinePos, 30 + dim.getWidth(), p); + + } + y += dim.getHeight() + 10; + } + final double linePos = linePos(stringBounder); + + final HLineCurved hlineIn = new HLineCurved(lastLinePos - linePos, 8); + hlineIn.drawU(ug.apply(new UTranslate(b, linePos))); + + final HLineCurved hlineOut = new HLineCurved(lastLinePos - linePos, -8); + hlineOut.drawU(ug.apply(new UTranslate(q, linePos))); + + } + + private void drawHline(UGraphic ug, double y, double x1, double x2) { + ug.apply(new UTranslate(x1, y)).draw(ULine.hline(x2 - x1)); + } + + @Override + public XDimension2D calculateDimension(StringBounder stringBounder) { + final Style style = getStyleSignature().getMergedStyle(styleBuilder); + final FontConfiguration fc = style.getFontConfiguration(colorSet); + double width = 0; + double height = 0; + for (String value : values) { + final ETile tile = new ETileBox(value, fc); + final XDimension2D dim = tile.calculateDimension(stringBounder); + height += dim.getHeight() + 10; + width = Math.max(width, dim.getWidth()); + } + width += 60; + return new XDimension2D(width, height); + } + + private StyleSignatureBasic getStyleSignature() { + return StyleSignatureBasic.of(SName.root, SName.element, SName.activityDiagram, SName.activity); + } + + @Override + public HColor getBackcolor() { + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/CornerCurved.java b/src/net/sourceforge/plantuml/ebnf/CornerCurved.java new file mode 100644 index 000000000..c243743b4 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/CornerCurved.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.ebnf; + +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPath; + +public class CornerCurved implements UDrawable { + + private final double delta; + + public CornerCurved(double delta) { + this.delta = delta; + } + + @Override + public void drawU(UGraphic ug) { + final UPath path = new UPath(); + path.moveTo(0, -Math.abs(delta)); + + final double a = delta / 4; + path.cubicTo(0, -Math.abs(a), a, 0, delta, 0); + + ug.draw(path); + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/ETile.java b/src/net/sourceforge/plantuml/ebnf/ETile.java new file mode 100644 index 000000000..c676cd319 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/ETile.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.ebnf; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; + +public interface ETile extends TextBlock { + + public double linePos(StringBounder stringBounder); + +} diff --git a/src/net/sourceforge/plantuml/ebnf/ETileBox.java b/src/net/sourceforge/plantuml/ebnf/ETileBox.java new file mode 100644 index 000000000..78e5d4ccb --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/ETileBox.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.ebnf; + +import net.sourceforge.plantuml.awt.geom.XDimension2D; +import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; +import net.sourceforge.plantuml.ugraphic.UText; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.ugraphic.color.HColors; + +public class ETileBox extends AbstractTextBlock implements ETile { + + private final String value; + private final FontConfiguration fc; + private final UText utext; + + public ETileBox(String value, FontConfiguration fc) { + this.value = value; + this.fc = fc; + this.utext = new UText(value, fc); + } + + @Override + public XDimension2D calculateDimension(StringBounder stringBounder) { + return XDimension2D.delta(getTextDim(stringBounder), 10); + } + + private XDimension2D getTextDim(StringBounder stringBounder) { + return stringBounder.calculateDimension(fc.getFont(), value); + } + + @Override + public void drawU(UGraphic ug) { + final XDimension2D dim = calculateDimension(ug.getStringBounder()); + final XDimension2D dimText = getTextDim(ug.getStringBounder()); + final URectangle rect = new URectangle(dim).rounded(10); + ug.apply(HColors.BLACK).apply(new UStroke(1.5)).draw(rect); + ug.apply(new UTranslate(5, 5 + dimText.getHeight() - utext.getDescent(ug.getStringBounder()))).draw(utext); + } + + @Override + public double linePos(StringBounder stringBounder) { + final double height = calculateDimension(stringBounder).getHeight(); + return height / 2; + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java b/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java new file mode 100644 index 000000000..2b7f34402 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/EbnfExpression.java @@ -0,0 +1,176 @@ +/* ======================================================================== + * 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.ebnf; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.UDrawable; + +interface CharIterator { + char peek(); + + void next(); +} + +class CharIteratorImpl implements CharIterator { + + final private List data; + private int line = 0; + private int pos = 0; + + public CharIteratorImpl(List data) { + this.data = data; + } + + public char peek() { + if (line == -1) + return 0; + return data.get(line).charAt(pos); + } + + public void next() { + if (line == -1) + throw new IllegalStateException(); + pos++; + if (pos >= data.get(line).length()) { + line++; + pos = 0; + } + if (line >= data.size()) + line = -1; + } +} + +public class EbnfExpression { + + final List tokens = new ArrayList<>(); + + public EbnfExpression(String... data) { + this(Arrays.asList(data)); + } + + public EbnfExpression(List data) { + final CharIterator it = new CharIteratorImpl(data); + analyze(it); + } + + public UDrawable getUDrawable(ISkinParam skinParam) { + final Iterator iterator = tokens.iterator(); + final Token name = iterator.next(); + final Token definition = iterator.next(); + final ShuntingYard shuntingYard = new ShuntingYard(iterator); + + return build(shuntingYard.getOuputQueue(), skinParam); + + } + + private Alternation build(Iterator it, ISkinParam skinParam) { + final Deque stack = new ArrayDeque<>(); + final Alternation ebnf = new Alternation(skinParam); + while (it.hasNext()) { + final Token element = it.next(); + if (element.getSymbol() == Symbol.TERMINAL_STRING1 || element.getSymbol() == Symbol.LITTERAL) { + stack.addFirst(element); + } else if (element.getSymbol() == Symbol.ALTERNATION) { + ebnf.alternation(stack.removeFirst()); + } else { + throw new UnsupportedOperationException(element.toString()); + } + } + ebnf.alternation(stack.removeFirst()); + + return ebnf; + } + + private void analyze(CharIterator it) { + while (true) { + final char ch = it.peek(); + if (Character.isWhitespace(ch)) { + } else if (isLetterOrDigit(ch)) { + final String litteral = readLitteral(it); + tokens.add(new Token(Symbol.LITTERAL, litteral)); + } else if (ch == '|') { + tokens.add(new Token(Symbol.ALTERNATION, null)); + } else if (ch == '=') { + tokens.add(new Token(Symbol.DEFINITION, null)); + } else if (ch == ';' || ch == 0) { + break; + } else if (ch == '\"') { + final String litteral = readString(it); + tokens.add(new Token(Symbol.TERMINAL_STRING1, litteral)); + } else + throw new UnsupportedOperationException("" + ch); + it.next(); + continue; + } + + } + + private String readString(CharIterator it) { + final char separator = it.peek(); + it.next(); + final StringBuilder sb = new StringBuilder(); + while (true) { + final char ch = it.peek(); + if (ch == separator) + return sb.toString(); + sb.append(ch); + it.next(); + } + } + + private String readLitteral(CharIterator it) { + final StringBuilder sb = new StringBuilder(); + while (true) { + final char ch = it.peek(); + if (isLetterOrDigit(ch) == false) + return sb.toString(); + sb.append(ch); + it.next(); + } + } + + private boolean isLetterOrDigit(char ch) { + return ch == '-' || ch == '_' || Character.isLetterOrDigit(ch); + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/HLineCurved.java b/src/net/sourceforge/plantuml/ebnf/HLineCurved.java new file mode 100644 index 000000000..cd0909e07 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/HLineCurved.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * 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.ebnf; + +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPath; + +public class HLineCurved implements UDrawable { + + private final double height; + private final double delta; + + public HLineCurved(double height, double delta) { + this.height = height; + this.delta = delta; + } + + @Override + public void drawU(UGraphic ug) { + if (delta == 0) { + ug.draw(ULine.vline(height)); + return; + } + final UPath path = new UPath(); + path.moveTo(-delta, 0); + + final double a = delta / 4; + path.cubicTo(-a, 0, 0, Math.abs(a), 0, Math.abs(delta)); + // path.lineTo(0, delta); + + path.lineTo(0, height - Math.abs(delta)); + + path.cubicTo(0, height - a, a, height, delta, height); + // path.lineTo(delta, height); + + ug.draw(path); + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java b/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java new file mode 100644 index 000000000..37a9477a7 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.ebnf; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.TitledDiagram; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.core.DiagramDescription; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.core.UmlSource; +import net.sourceforge.plantuml.graphic.UDrawable; + +public class PSystemEbnf extends TitledDiagram { + + private final List lines = new ArrayList<>(); + + public PSystemEbnf(UmlSource source) { + super(source, UmlDiagramType.EBNF, null); + } + + public DiagramDescription getDescription() { + return new DiagramDescription("(EBNF)"); + } + + public void doCommandLine(String line) { + lines.add(line); + } + + @Override + protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption) + throws IOException { + return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os); + } + + private UDrawable getTextBlock() { + final EbnfExpression exp = new EbnfExpression(lines); + return exp.getUDrawable(getSkinParam()); + } +} diff --git a/src/net/sourceforge/plantuml/ebnf/PSystemEbnfFactory.java b/src/net/sourceforge/plantuml/ebnf/PSystemEbnfFactory.java new file mode 100644 index 000000000..5448f45f3 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/PSystemEbnfFactory.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.ebnf; + +import net.sourceforge.plantuml.command.PSystemBasicFactory; +import net.sourceforge.plantuml.core.DiagramType; +import net.sourceforge.plantuml.core.UmlSource; + +public class PSystemEbnfFactory extends PSystemBasicFactory { + + public PSystemEbnfFactory() { + super(DiagramType.EBNF); + } + + @Override + public PSystemEbnf initDiagram(UmlSource source, String startLine) { + if (getDiagramType() == DiagramType.EBNF) + return new PSystemEbnf(source); + + return null; + } + + @Override + public PSystemEbnf executeLine(UmlSource source, PSystemEbnf system, String line) { + system.doCommandLine(line); + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/ShuntingYard.java b/src/net/sourceforge/plantuml/ebnf/ShuntingYard.java new file mode 100644 index 000000000..c8d503dd0 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/ShuntingYard.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.ebnf; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; + +public class ShuntingYard { + + final private List ouputQueue = new ArrayList<>(); + final private Deque operatorStack = new ArrayDeque<>(); + + public ShuntingYard(Iterator it) { + while (it.hasNext()) { + final Token token = it.next(); + if (token.getSymbol() == Symbol.LITTERAL || token.getSymbol() == Symbol.TERMINAL_STRING1) { + ouputQueue.add(token); + } else if (token.getSymbol() == Symbol.ALTERNATION) { + operatorStack.addFirst(token); + } else { + throw new UnsupportedOperationException(token.toString()); + } + + } + while (operatorStack.isEmpty() == false) { + final Token token = operatorStack.removeFirst(); + ouputQueue.add(token); + } + } + + public final Iterator getOuputQueue() { + return ouputQueue.iterator(); + } + +} diff --git a/src/net/sourceforge/plantuml/ebnf/Symbol.java b/src/net/sourceforge/plantuml/ebnf/Symbol.java new file mode 100644 index 000000000..6499e5860 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/Symbol.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.ebnf; + +public enum Symbol { + + LITTERAL, // + + // https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form + DEFINITION, // = + CONCATENATION, // , + TERMINATION, // ; + ALTERNATION, // | + OPTIONAL, // [ ] + REPETITION, // { } + GROUPING, // ( ) + TERMINAL_STRING1, // " " + TERMINAL_STRING2, // ' ' + COMMENT, // (* *) + SPECIAL_SEQUENCE, // ? ? + EXCEPTION; // - + +} diff --git a/src/net/sourceforge/plantuml/ebnf/Token.java b/src/net/sourceforge/plantuml/ebnf/Token.java new file mode 100644 index 000000000..c135b1545 --- /dev/null +++ b/src/net/sourceforge/plantuml/ebnf/Token.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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.ebnf; + +public class Token { + + private final Symbol symbol; + private final String data; + + public Token(Symbol symbol, String data) { + this.symbol = symbol; + this.data = data; + } + + @Override + public String toString() { + if (data == null) + return symbol.toString(); + return symbol.toString() + " " + data; + } + + public final Symbol getSymbol() { + return symbol; + } + + public final String getData() { + return data; + } + +} diff --git a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java index e55acd106..0835fe90d 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java +++ b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java @@ -78,12 +78,12 @@ public class JsonDiagram extends TitledDiagram { } public DiagramDescription getDescription() { - if (getUmlDiagramType() == UmlDiagramType.YAML) { + if (getUmlDiagramType() == UmlDiagramType.YAML) return new DiagramDescription("(Yaml)"); - } - if (getUmlDiagramType() == UmlDiagramType.HCL) { + + if (getUmlDiagramType() == UmlDiagramType.HCL) return new DiagramDescription("(HCL)"); - } + return new DiagramDescription("(Json)"); } diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java index fcd044919..a7b085e77 100644 --- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java +++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -54,7 +55,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandMindMapOrgmodeMultiline extends CommandMultilines2 { public CommandMindMapOrgmodeMultiline() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } static IRegex getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java index affb65f0d..8d1483e9f 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java @@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -61,7 +62,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandCreateEntityObjectMultilines extends CommandMultilines2 { public CommandCreateEntityObjectMultilines() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } private static IRegex getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java index 85d47a803..e0e2e2a60 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java @@ -43,6 +43,7 @@ import net.sourceforge.plantuml.command.CommandControl; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -65,7 +66,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandCreateJson extends CommandMultilines2 { public CommandCreateJson() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } private static IRegex getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java index 32511b328..3e166990c 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java @@ -43,6 +43,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -69,7 +70,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandCreateMap extends CommandMultilines2 { public CommandCreateMap() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } private static IRegex getRegexConcat() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java index 1330212a4..90c3d74e6 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java @@ -44,6 +44,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; @@ -60,7 +61,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandParticipantMultilines extends CommandMultilines2 { public CommandParticipantMultilines() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java b/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java index 33fdad7d7..f2b198098 100644 --- a/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java +++ b/src/net/sourceforge/plantuml/style/CommandStyleMultilinesCSS.java @@ -41,6 +41,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -48,7 +49,7 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf; public class CommandStyleMultilinesCSS extends CommandMultilines2 { public CommandStyleMultilinesCSS() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java b/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java index 8a9e5f516..1ac9a1885 100644 --- a/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java +++ b/src/net/sourceforge/plantuml/tim/expression/ShuntingYard.java @@ -73,9 +73,9 @@ public class ShuntingYard { final String name = token.getSurface(); final TValue variable = knowledge.getVariable(name); if (variable == null) { - if (isVariableName(name) == false) { + if (isVariableName(name) == false) throw EaterException.unlocated("Parsing syntax error about " + name); - } + ouputQueue.add(new Token(name, TokenType.QUOTED_STRING, null)); } else { ouputQueue.add(variable.toToken()); @@ -84,9 +84,9 @@ public class ShuntingYard { while ((thereIsAFunctionAtTheTopOfTheOperatorStack(token) // || thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(token) // || theOperatorAtTheTopOfTheOperatorStackHasEqualPrecedenceAndIsLeftAssociative(token)) // - && theOperatorAtTheTopOfTheOperatorStackIsNotALeftParenthesis(token)) { + && theOperatorAtTheTopOfTheOperatorStackIsNotALeftParenthesis(token)) ouputQueue.add(operatorStack.removeFirst()); - } + // push it onto the operator stack. operatorStack.addFirst(token); } else if (token.getTokenType() == TokenType.OPEN_PAREN_FUNC) { @@ -97,17 +97,17 @@ public class ShuntingYard { final Token first = operatorStack.removeFirst(); ouputQueue.add(first); } else if (token.getTokenType() == TokenType.CLOSE_PAREN_MATH) { - while (operatorStack.peekFirst().getTokenType() != TokenType.OPEN_PAREN_MATH) { + while (operatorStack.peekFirst().getTokenType() != TokenType.OPEN_PAREN_MATH) ouputQueue.add(operatorStack.removeFirst()); - } - if (operatorStack.peekFirst().getTokenType() == TokenType.OPEN_PAREN_MATH) { + + if (operatorStack.peekFirst().getTokenType() == TokenType.OPEN_PAREN_MATH) operatorStack.removeFirst(); - } + } else if (token.getTokenType() == TokenType.COMMA) { while (operatorStack.peekFirst() != null - && operatorStack.peekFirst().getTokenType() != TokenType.OPEN_PAREN_FUNC) { + && operatorStack.peekFirst().getTokenType() != TokenType.OPEN_PAREN_FUNC) ouputQueue.add(operatorStack.removeFirst()); - } + } else { throw new UnsupportedOperationException(token.toString()); } @@ -133,26 +133,26 @@ public class ShuntingYard { private boolean thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(Token token) { final Token top = operatorStack.peekFirst(); if (top != null && top.getTokenType() == TokenType.OPERATOR - && top.getTokenOperator().getPrecedence() > token.getTokenOperator().getPrecedence()) { + && 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()) { + && 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) { + if (top != null && top.getTokenType() == TokenType.OPEN_PAREN_MATH) return true; - } + return true; } diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java index 70f90e457..f4ce89a61 100644 --- a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java +++ b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java @@ -107,11 +107,10 @@ public class TokenStack { public TokenStack withoutSpace() { final TokenStack result = new TokenStack(); - for (Token token : tokens) { - if (token.getTokenType() != TokenType.SPACES) { + for (Token token : tokens) + if (token.getTokenType() != TokenType.SPACES) result.add(token); - } - } + return result; } @@ -121,19 +120,19 @@ public class TokenStack { while (true) { eater.skipSpaces(); final char ch = eater.peekChar(); - if (ch == 0) { + if (ch == 0) throw EaterException.unlocated("until001"); - } - if (level == 0 && (ch == ',' || ch == ')')) { + + if (level == 0 && (ch == ',' || ch == ')')) return result; - } + final Token token = TokenType.eatOneToken(eater, false); final TokenType type = token.getTokenType(); - if (type == TokenType.OPEN_PAREN_MATH) { + if (type == TokenType.OPEN_PAREN_MATH) level++; - } else if (type == TokenType.CLOSE_PAREN_MATH) { + else if (type == TokenType.CLOSE_PAREN_MATH) level--; - } + result.add(token); } } @@ -142,42 +141,42 @@ public class TokenStack { int level = 0; while (true) { final Token ch = it.peekToken(); - if (ch == null) { + if (ch == null) throw EaterException.unlocated("until002"); - } + final TokenType typech = ch.getTokenType(); if (level == 0 && (typech == TokenType.COMMA || typech == TokenType.CLOSE_PAREN_MATH) - || typech == TokenType.CLOSE_PAREN_FUNC) { + || 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) { + if (type == TokenType.OPEN_PAREN_MATH || type == TokenType.OPEN_PAREN_FUNC) level++; - } else if (type == TokenType.CLOSE_PAREN_MATH || type == TokenType.CLOSE_PAREN_FUNC) { + 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) { + 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) { + if (type == TokenType.CLOSE_PAREN_MATH || type == TokenType.CLOSE_PAREN_FUNC) return result; - } else if (type == TokenType.COMMA) { + else if (type == TokenType.COMMA) result++; - } else { + else throw EaterException.unlocated("count13"); - } + } throw EaterException.unlocated("count12"); } @@ -187,11 +186,11 @@ public class TokenStack { 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)) { + if (token.getTokenType().equals(TokenType.OPEN_PAREN_MATH)) open.addFirst(i); - } else if (token.getTokenType().equals(TokenType.CLOSE_PAREN_MATH)) { + else if (token.getTokenType().equals(TokenType.CLOSE_PAREN_MATH)) parens.put(open.pollFirst(), i); - } + } // System.err.println("before=" + toString()); // System.err.println("guessFunctions2" + parens); @@ -219,9 +218,9 @@ public class TokenStack { } public Token nextToken() { - if (hasMoreTokens() == false) { + if (hasMoreTokens() == false) return null; - } + return tokens.get(pos++); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/command/CommandNoteLong.java b/src/net/sourceforge/plantuml/timingdiagram/command/CommandNoteLong.java index 4714cfef5..c4573840e 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/command/CommandNoteLong.java +++ b/src/net/sourceforge/plantuml/timingdiagram/command/CommandNoteLong.java @@ -40,6 +40,7 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; import net.sourceforge.plantuml.command.Position; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; @@ -53,7 +54,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandNoteLong extends CommandMultilines2 { public CommandNoteLong() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } @Override diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index e3f12b42f..6e052894c 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -81,7 +81,7 @@ public class Version { } public static int beta() { - final int beta = 9; + final int beta = 11; return beta; } diff --git a/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.java b/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.java index a3dafb2d2..a60ccd5ac 100644 --- a/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.java +++ b/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.java @@ -43,6 +43,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.Trim; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.RegexConcat; @@ -56,7 +57,7 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; public class CommandWBSItemMultiline extends CommandMultilines2 { public CommandWBSItemMultiline() { - super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE, Trim.BOTH); } static IRegex getRegexConcat() {