diff --git a/pom.xml b/pom.xml index 2cc735b18..1b20cec86 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ net.sourceforge.plantuml plantuml - 1.2020.9 + 1.2020.11-SNAPSHOT jar PlantUML @@ -75,9 +75,9 @@ - scm:svn:svn://svn.code.sf.net/p/plantuml/code/tags/plantuml-1.2020.9 - scm:svn:https://svn.code.sf.net/p/plantuml/code/tags/plantuml-1.2020.9 - svn://svn.code.sf.net/p/plantuml/code/tags/plantuml-1.2020.9 + scm:svn:svn://svn.code.sf.net/p/plantuml/code/trunk + scm:svn:https://svn.code.sf.net/p/plantuml/code/trunk + svn://svn.code.sf.net/p/plantuml/code/trunk diff --git a/src/net/sourceforge/plantuml/AbstractPSystem.java b/src/net/sourceforge/plantuml/AbstractPSystem.java index 64638e569..5ef76eef3 100644 --- a/src/net/sourceforge/plantuml/AbstractPSystem.java +++ b/src/net/sourceforge/plantuml/AbstractPSystem.java @@ -75,7 +75,12 @@ public abstract class AbstractPSystem implements Diagram { if (source == null) { return getVersion(); } - return source.getPlainString() + BackSlash.NEWLINE + getVersion(); + final String rawString = source.getRawString(); + final String plainString = source.getPlainString(); + if (rawString != null && rawString.equals(plainString)) { + return rawString + BackSlash.NEWLINE + getVersion(); + } + return rawString + BackSlash.NEWLINE + plainString + BackSlash.NEWLINE + getVersion(); } final public UmlSource getSource() { diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index d4547ef68..65af8b9c1 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -59,6 +59,7 @@ import net.sourceforge.plantuml.version.Version; public class BlockUml { + private final List rawSource; private final List data; private List debug; private Diagram system; @@ -108,6 +109,7 @@ public class BlockUml { private boolean preprocessorError; public BlockUml(List strings, Defines defines, ISkinSimple skinParam, PreprocessorModeSet mode) { + this.rawSource = new ArrayList(strings); this.localDefines = defines; this.skinParam = skinParam; final String s0 = strings.get(0).getTrimmed().getString(); @@ -158,7 +160,7 @@ public class BlockUml { if (preprocessorError) { system = new PSystemErrorPreprocessor(data, debug); } else { - system = new PSystemBuilder().createPSystem(skinParam, data); + system = new PSystemBuilder().createPSystem(skinParam, data, rawSource); } } return system; diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java index b103ea1bc..a9dd1af39 100644 --- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -87,12 +87,12 @@ public final class BlockUmlBuilder implements DefinitionsContainer { private void init(ReadLineNumbered includer) throws IOException { StringLocated s = null; - List current2 = null; + List current = null; boolean paused = false; while ((s = includer.readLine()) != null) { if (StartUtils.isArobaseStartDiagram(s.getString())) { - current2 = new ArrayList(); + current = new ArrayList(); paused = false; } if (StartUtils.isArobasePauseDiagram(s.getString())) { @@ -103,12 +103,12 @@ public final class BlockUmlBuilder implements DefinitionsContainer { paused = true; reader.setPaused(true); } - if (current2 != null && paused == false) { - current2.add(s); + if (current != null && paused == false) { + current.add(s); } else if (paused) { final StringLocated append = StartUtils.getPossibleAppend(s); if (append != null) { - current2.add(append); + current.add(append); } } @@ -116,14 +116,14 @@ public final class BlockUmlBuilder implements DefinitionsContainer { paused = false; reader.setPaused(false); } - if (StartUtils.isArobaseEndDiagram(s.getString()) && current2 != null) { + if (StartUtils.isArobaseEndDiagram(s.getString()) && current != null) { if (paused) { - current2.add(s); + current.add(s); } - final BlockUml uml = new BlockUml(current2, defines.cloneMe(), null, this); + final BlockUml uml = new BlockUml(current, defines.cloneMe(), null, this); usedFiles.addAll(uml.getIncluded()); blocks.add(uml); - current2 = null; + current = null; reader.setPaused(false); } } diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 98daca766..0e861c4a2 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.command.regex.RegexConcat; 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.creole.legacy.PSystemCreoleFactory; import net.sourceforge.plantuml.dedication.PSystemDedicationFactory; import net.sourceforge.plantuml.definition.PSystemDefinitionFactory; import net.sourceforge.plantuml.descdiagram.DescriptionDiagramFactory; @@ -96,24 +96,24 @@ 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, List source, + List rawSource) { final long now = System.currentTimeMillis(); Diagram result = null; try { - final DiagramType type = DiagramType.getTypeFromArobaseStart(strings2.get(0).getString()); - final UmlSource umlSource = new UmlSource(strings2, type == DiagramType.UML); + final DiagramType type = DiagramType.getTypeFromArobaseStart(source.get(0).getString()); + final UmlSource umlSource = new UmlSource(source, type == DiagramType.UML, rawSource); - for (StringLocated s : strings2) { + for (StringLocated s : source) { if (s.getPreprocessorError() != null) { // Dead code : should not append + assert false; Log.error("Preprocessor Error: " + s.getPreprocessorError()); final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, s.getPreprocessorError(), /* cpt */ s.getLocation()); - // return PSystemErrorUtils.buildV1(umlSource, err, Collections. - // emptyList()); - return PSystemErrorUtils.buildV2(umlSource, err, Collections.emptyList(), strings2); + return PSystemErrorUtils.buildV2(umlSource, err, Collections.emptyList(), source); } } diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index b4fd8cb47..536e1cbf0 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -52,7 +52,7 @@ import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.command.CommandCreoleMonospaced; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.cucadiagram.LinkStyle; import net.sourceforge.plantuml.cucadiagram.Rankdir; import net.sourceforge.plantuml.cucadiagram.Stereotype; @@ -1082,7 +1082,7 @@ public class SkinParam implements ISkinParam { public String getMonospacedFamily() { final String value = getValue("defaultMonospacedFontName"); if (value == null) { - return CommandCreoleMonospaced.MONOSPACED; + return Parser.MONOSPACED; } return value; } diff --git a/src/net/sourceforge/plantuml/SpriteContainerEmpty.java b/src/net/sourceforge/plantuml/SpriteContainerEmpty.java index 063a82a84..a5361f1c5 100644 --- a/src/net/sourceforge/plantuml/SpriteContainerEmpty.java +++ b/src/net/sourceforge/plantuml/SpriteContainerEmpty.java @@ -37,7 +37,7 @@ package net.sourceforge.plantuml; import java.util.Map; -import net.sourceforge.plantuml.creole.command.CommandCreoleMonospaced; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.sprite.Sprite; import net.sourceforge.plantuml.sprite.SpriteImage; import net.sourceforge.plantuml.ugraphic.color.ColorMapper; @@ -63,7 +63,7 @@ public class SpriteContainerEmpty implements SpriteContainer, ISkinSimple { } public String getMonospacedFamily() { - return CommandCreoleMonospaced.MONOSPACED; + return Parser.MONOSPACED; } public int getTabSize() { @@ -85,15 +85,13 @@ public class SpriteContainerEmpty implements SpriteContainer, ISkinSimple { public ColorMapper getColorMapper() { return new ColorMapperIdentity(); } - + public void copyAllFrom(ISkinSimple other) { throw new UnsupportedOperationException(); } - + public Map values() { throw new UnsupportedOperationException(); } - - } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/UmlDiagram.java b/src/net/sourceforge/plantuml/UmlDiagram.java index 8f8beb03d..a9c9961a5 100644 --- a/src/net/sourceforge/plantuml/UmlDiagram.java +++ b/src/net/sourceforge/plantuml/UmlDiagram.java @@ -189,8 +189,7 @@ public abstract class UmlDiagram extends TitledDiagram implements Diagram, Annot fileFormatOption = fileFormatOption.withPreserveAspectRatio(getSkinParam().getPreserveAspectRatio()); fileFormatOption = fileFormatOption.withTikzFontDistortion(getSkinParam().getTikzFontDistortion()); if (hover != null) { - fileFormatOption = fileFormatOption - .withHoverColor(getSkinParam().getColorMapper().toHtml(hover)); + fileFormatOption = fileFormatOption.withHoverColor(getSkinParam().getColorMapper().toHtml(hover)); } if (fileFormatOption.getFileFormat() == FileFormat.PDF) { @@ -230,15 +229,19 @@ public abstract class UmlDiagram extends TitledDiagram implements Diagram, Annot strings.addAll(CommandExecutionResult.getStackTrace(exception)); - final ImageBuilder imageBuilder = ImageBuilder.buildA(new ColorMapperIdentity(), false, - null, metadata, null, 1.0, HColorUtils.WHITE); + final ImageBuilder imageBuilder = ImageBuilder.buildA(new ColorMapperIdentity(), false, null, metadata, null, + 1.0, HColorUtils.WHITE); - final FlashCodeUtils utils = FlashCodeFactory.getFlashCodeUtils(); - final BufferedImage im = utils.exportFlashcode(flash, Color.BLACK, Color.WHITE); - if (im != null) { - GraphvizCrash.addDecodeHint(strings); + final BufferedImage im; + if (flash == null) { + im = null; + } else { + final FlashCodeUtils utils = FlashCodeFactory.getFlashCodeUtils(); + im = utils.exportFlashcode(flash, Color.BLACK, Color.WHITE); + if (im != null) { + GraphvizCrash.addDecodeHint(strings); + } } - final TextBlockBackcolored graphicStrings = GraphicStrings.createBlackOnWhite(strings, IconLoader.getRandom(), GraphicPosition.BACKGROUND_CORNER_TOP_RIGHT); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/CollisionDetector.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/CollisionDetector.java index 72539f63c..f01dab4ad 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/CollisionDetector.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/CollisionDetector.java @@ -45,6 +45,7 @@ import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.UBackground; import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicNo; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UParamNull; @@ -57,7 +58,7 @@ import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorUtils; -public class CollisionDetector implements UGraphic { +public class CollisionDetector extends UGraphicNo implements UGraphic { public UGraphic apply(UChange change) { if (change instanceof UTranslate) { @@ -199,12 +200,6 @@ public class CollisionDetector implements UGraphic { throw new UnsupportedOperationException(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public void flushUg() { } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileWithUrl.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileWithUrl.java index c0233a65e..d43f9150a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileWithUrl.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileWithUrl.java @@ -54,7 +54,7 @@ public class FtileWithUrl extends FtileDecorate { public void drawU(UGraphic ug) { ug.startUrl(url); getFtileDelegated().drawU(ug); - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/ZadBuilder.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/ZadBuilder.java index 5a7d3f82a..520bbdbf2 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/ZadBuilder.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/ZadBuilder.java @@ -35,12 +35,12 @@ */ package net.sourceforge.plantuml.activitydiagram3.ftile; -import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.UBackground; import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicNo; import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UParamNull; import net.sourceforge.plantuml.ugraphic.URectangle; @@ -50,7 +50,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.HColor; -public class ZadBuilder implements UGraphic { +public class ZadBuilder extends UGraphicNo implements UGraphic { public UGraphic apply(UChange change) { if (change instanceof UTranslate) { @@ -111,12 +111,6 @@ public class ZadBuilder implements UGraphic { throw new UnsupportedOperationException(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public void flushUg() { } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FloatingNote.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FloatingNote.java index 3da553f1f..33c7962e9 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FloatingNote.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FloatingNote.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; @@ -72,11 +72,13 @@ public class FloatingNote extends AbstractTextBlock implements Stencil, TextBloc final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.NOTE, null); - final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), - skinParam, CreoleMode.FULL).createSheet(note); - final SheetBlock2 sheetBlock2 = new SheetBlock2(new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()), this, - new UStroke(1)); - final double shadowing;shadowing = skinParam.shadowing(null)?4:0; + final Sheet sheet = Parser + .build(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL) + .createSheet(note); + final SheetBlock2 sheetBlock2 = new SheetBlock2( + new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()), this, new UStroke(1)); + final double shadowing; + shadowing = skinParam.shadowing(null) ? 4 : 0; this.opale = new Opale(shadowing, borderColor, noteBackgroundColor, sheetBlock2, false); // this.text = sheetBlock2; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfAndStop.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfAndStop.java index 02eda2028..a1e6a0eb2 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfAndStop.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileIfAndStop.java @@ -61,7 +61,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamond; import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamondInside; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; @@ -124,13 +124,15 @@ class FtileIfAndStop extends AbstractFtile { final Ftile stopFtile = ftileFactory.stop(swimlane); - // final TextBlock tb1 = Display.create(branch1.getLabelPositive(), fcArrow, HorizontalAlignment.LEFT, + // final TextBlock tb1 = Display.create(branch1.getLabelPositive(), fcArrow, + // HorizontalAlignment.LEFT, // ftileFactory); - // final TextBlock tb2 = Display.create(branch2.getLabelPositive(), fcArrow, HorizontalAlignment.LEFT, + // final TextBlock tb2 = Display.create(branch2.getLabelPositive(), fcArrow, + // HorizontalAlignment.LEFT, // ftileFactory); - final Sheet sheet = new CreoleParser(fcTest, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), - skinParam, CreoleMode.FULL).createSheet(labelTest); + final Sheet sheet = Parser.build(fcTest, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL) + .createSheet(labelTest); final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()); final TextBlock tbTest = new SheetBlock2(sheetBlock1, Diamond.asStencil(sheetBlock1), tileNonStop.getThickness()); @@ -149,9 +151,11 @@ class FtileIfAndStop extends AbstractFtile { // final Ftile diamond2; // if (tile1.calculateDimension(stringBounder).hasPointOut() // && tile2.calculateDimension(stringBounder).hasPointOut()) { - // diamond2 = new FtileDiamond(tile1.shadowing(), backColor, borderColor, swimlane); + // diamond2 = new FtileDiamond(tile1.shadowing(), backColor, borderColor, + // swimlane); // } else { - // diamond2 = new FtileEmpty(tile1.shadowing(), Diamond.diamondHalfSize * 2, Diamond.diamondHalfSize * 2, + // diamond2 = new FtileEmpty(tile1.shadowing(), Diamond.diamondHalfSize * 2, + // Diamond.diamondHalfSize * 2, // swimlane, swimlane); // } final FtileIfAndStop result = new FtileIfAndStop(diamond1, tileNonStop, arrowColor, stopFtile); @@ -161,14 +165,18 @@ class FtileIfAndStop extends AbstractFtile { // conns.add(result.new ConnectionHorizontalThenVertical(tile2)); // if (tile1.calculateDimension(stringBounder).hasPointOut() // && tile2.calculateDimension(stringBounder).hasPointOut()) { - // conns.add(result.new ConnectionVerticalThenHorizontal(tile1, branch1.getInlinkRenderingColor())); - // conns.add(result.new ConnectionVerticalThenHorizontal(tile2, branch2.getInlinkRenderingColor())); + // conns.add(result.new ConnectionVerticalThenHorizontal(tile1, + // branch1.getInlinkRenderingColor())); + // conns.add(result.new ConnectionVerticalThenHorizontal(tile2, + // branch2.getInlinkRenderingColor())); // } else if (tile1.calculateDimension(stringBounder).hasPointOut() // && tile2.calculateDimension(stringBounder).hasPointOut() == false) { - // conns.add(result.new ConnectionVerticalThenHorizontalDirect(tile1, branch1.getInlinkRenderingColor())); + // conns.add(result.new ConnectionVerticalThenHorizontalDirect(tile1, + // branch1.getInlinkRenderingColor())); // } else if (tile1.calculateDimension(stringBounder).hasPointOut() == false // && tile2.calculateDimension(stringBounder).hasPointOut()) { - // conns.add(result.new ConnectionVerticalThenHorizontalDirect(tile2, branch2.getInlinkRenderingColor())); + // conns.add(result.new ConnectionVerticalThenHorizontalDirect(tile2, + // branch2.getInlinkRenderingColor())); // } return FtileUtils.addConnection(result, conns); // return result; @@ -281,7 +289,8 @@ class FtileIfAndStop extends AbstractFtile { // final Dimension2D dimTotal = calculateDimensionInternal(stringBounder); // if (tile1.calculateDimension(stringBounder).hasPointOut()) { - // return new FtileGeometry(dimTotal, getLeft(stringBounder), 0, dimTotal.getHeight()); + // return new FtileGeometry(dimTotal, getLeft(stringBounder), 0, + // dimTotal.getHeight()); // } // return new FtileGeometry(dimTotal, getLeft(stringBounder), 0); } @@ -295,22 +304,26 @@ class FtileIfAndStop extends AbstractFtile { // return calculateDimensionInternal; // } // - // private Dimension2D calculateDimensionInternalSlow(StringBounder stringBounder) { + // private Dimension2D calculateDimensionInternalSlow(StringBounder + // stringBounder) { // final Dimension2D dim1 = tile1.calculateDimension(stringBounder); // final Dimension2D dimDiamond1 = diamond1.calculateDimension(stringBounder); // final Dimension2D dimStop2 = stop2.calculateDimension(stringBounder); // final double width = Math.max(dim1.getWidth(), // dimDiamond1.getWidth() + getDiamondStopDistance() + dimStop2.getWidth()); - // return new Dimension2DDouble(width + 30, dim1.getHeight() + dimDiamond1.getHeight() + 40); + // return new Dimension2DDouble(width + 30, dim1.getHeight() + + // dimDiamond1.getHeight() + 40); // } // // private double getLeft(StringBounder stringBounder) { // // return calculateDimension(stringBounder).getLeft(); - // return tile1.calculateDimension(stringBounder).translate(getTranslate1(stringBounder)).getLeft(); + // return + // tile1.calculateDimension(stringBounder).translate(getTranslate1(stringBounder)).getLeft(); // // final double left1 = // tile1.calculateDimension(stringBounder).translate(getTranslate1(stringBounder)).getLeft(); // // // final double left2 = - // // // tile2.calculateDimension(stringBounder).translate(getTranslate2(stringBounder)).getLeft(); + // // // + // tile2.calculateDimension(stringBounder).translate(getTranslate2(stringBounder)).getLeft(); // // // return (left1 + left2) / 2; // // return left1; // } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileNoteAlone.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileNoteAlone.java index 0efb9abed..33e17c62e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileNoteAlone.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileNoteAlone.java @@ -50,7 +50,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; @@ -123,8 +123,9 @@ public class FtileNoteAlone extends AbstractFtile implements Stencil, Styleable final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.NOTE, null); - final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), - skinParam, CreoleMode.FULL).createSheet(note); + final Sheet sheet = Parser + .build(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL) + .createSheet(note); final TextBlock text = new SheetBlock2(new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()), this, new UStroke(1)); opale = new Opale(shadowing, borderColor, noteBackgroundColor, text, false); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java index 7a4b0a9ca..27b3d9e3b 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java @@ -55,7 +55,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; @@ -144,7 +144,8 @@ public class FtileWithNoteOpale extends AbstractFtile implements Stencil, Stylea final double shadowing; if (SkinParam.USE_STYLES()) { - final Style style = getDefaultStyleDefinition().getMergedStyle(skinParam.getCurrentStyleBuilder()).eventuallyOverride(note.getColors()); + final Style style = getDefaultStyleDefinition().getMergedStyle(skinParam.getCurrentStyleBuilder()) + .eventuallyOverride(note.getColors()); noteBackgroundColor = style.value(PName.BackGroundColor).asColor(getIHtmlColorSet()); borderColor = style.value(PName.LineColor).asColor(getIHtmlColorSet()); fc = style.getFontConfiguration(getIHtmlColorSet()); @@ -158,7 +159,7 @@ public class FtileWithNoteOpale extends AbstractFtile implements Stencil, Stylea final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false); - final Sheet sheet = new CreoleParser(fc, align, skinParam, CreoleMode.FULL).createSheet(note.getDisplay()); + final Sheet sheet = Parser.build(fc, align, skinParam, CreoleMode.FULL).createSheet(note.getDisplay()); final TextBlock text = new SheetBlock2(new SheetBlock1(sheet, skinParam.wrapWidth(), skinParam.getPadding()), this, new UStroke(1)); opale = new Opale(shadowing, borderColor, noteBackgroundColor, text, withLink); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNotes.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNotes.java index ef52afe82..6edb06090 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNotes.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNotes.java @@ -51,7 +51,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; @@ -129,8 +129,9 @@ public class FtileWithNotes extends AbstractFtile { shadowing = skinParam.shadowing(null) ? 4 : 0; } - final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), - skinParam, CreoleMode.FULL).createSheet(note.getDisplay()); + final Sheet sheet = Parser + .build(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL) + .createSheet(note.getDisplay()); final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()); final SheetBlock2 sheet2 = new SheetBlock2(sheet1, new Stencil() { // -6 and 15 value comes from Opale: this is very ugly! diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/ConditionalBuilder.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/ConditionalBuilder.java index 7c3beb498..7cd697b2e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/ConditionalBuilder.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/ConditionalBuilder.java @@ -54,10 +54,11 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileIfDown; import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamond; import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamondInside; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; +import net.sourceforge.plantuml.creole.legacy.CreoleParser; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -107,12 +108,12 @@ public class ConditionalBuilder { if (SkinParam.USE_STYLES()) { final Style styleArrow = getDefaultStyleDefinitionArrow() .getMergedStyle(skinParam.getCurrentStyleBuilder()); - final Style styleDiamond = getDefaultStyleDefinitionDiamond().getMergedStyle( - skinParam.getCurrentStyleBuilder()); + final Style styleDiamond = getDefaultStyleDefinitionDiamond() + .getMergedStyle(skinParam.getCurrentStyleBuilder()); this.borderColor = styleDiamond.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()); this.backColor = styleDiamond.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet()); - this.arrowColor = Rainbow - .fromColor(styleArrow.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()), null); + this.arrowColor = Rainbow.fromColor(styleArrow.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()), + null); this.fontTest = styleDiamond.getFontConfiguration(skinParam.getIHtmlColorSet()); this.fontArrow = styleArrow.getFontConfiguration(skinParam.getIHtmlColorSet()); } else { @@ -238,7 +239,7 @@ public class ConditionalBuilder { private Ftile getDiamond1(boolean eastWest, TextBlock tb1, TextBlock tb2) { final Display labelTest = branch1.getLabelTest(); - final Sheet sheet = new CreoleParser(fontTest, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), + final Sheet sheet = Parser.build(fontTest, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL).createSheet(labelTest); final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()); final TextBlock tbTest = new SheetBlock2(sheetBlock1, Diamond.asStencil(sheetBlock1), tile1.getThickness()); @@ -279,11 +280,13 @@ public class ConditionalBuilder { // else use default ConditionEndStyle.DIAMOND if (hasTwoBranches()) { final Display out1 = branch1.getFtile().getOutLinkRendering().getDisplay(); - final TextBlock tbout1 = out1 == null ? null : out1.create7(fontArrow, HorizontalAlignment.LEFT, - ftileFactory.skinParam(), CreoleMode.SIMPLE_LINE); + final TextBlock tbout1 = out1 == null ? null + : out1.create7(fontArrow, HorizontalAlignment.LEFT, ftileFactory.skinParam(), + CreoleMode.SIMPLE_LINE); final Display out2 = branch2.getFtile().getOutLinkRendering().getDisplay(); - final TextBlock tbout2 = out2 == null ? null : out2.create7(fontArrow, HorizontalAlignment.LEFT, - ftileFactory.skinParam(), CreoleMode.SIMPLE_LINE); + final TextBlock tbout2 = out2 == null ? null + : out2.create7(fontArrow, HorizontalAlignment.LEFT, ftileFactory.skinParam(), + CreoleMode.SIMPLE_LINE); FtileDiamond tmp = new FtileDiamond(tile1.skinParam(), backColor, borderColor, swimlane); tmp = useNorth ? tmp.withNorth(tbout1) : tmp.withWest(tbout1); tmp = tmp.withEast(tbout2); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java index ca00434b9..f65f04adb 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java @@ -55,11 +55,12 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; import net.sourceforge.plantuml.creole.Stencil; +import net.sourceforge.plantuml.creole.legacy.CreoleParser; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -216,8 +217,9 @@ public class FtileBox extends AbstractFtile { wrapWidth = skinParam.wrapWidth(); } - final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(horizontalAlignment), skinParam, - CreoleMode.FULL).createSheet(label); + final Sheet sheet = Parser + .build(fc, skinParam.getDefaultTextAlignment(horizontalAlignment), skinParam, CreoleMode.FULL) + .createSheet(label); this.tb = new SheetBlock2(new SheetBlock1(sheet, wrapWidth, skinParam.getPadding()), new MyStencil(), new UStroke(1)); this.print = label.toString(); diff --git a/src/net/sourceforge/plantuml/braille/UGraphicBraille.java b/src/net/sourceforge/plantuml/braille/UGraphicBraille.java index 43521810b..c281eecee 100644 --- a/src/net/sourceforge/plantuml/braille/UGraphicBraille.java +++ b/src/net/sourceforge/plantuml/braille/UGraphicBraille.java @@ -121,12 +121,6 @@ public class UGraphicBraille extends AbstractUGraphic implements Cl return FileFormat.BRAILLE_PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public void writeImageTOBEMOVED(OutputStream os, String metadata, int dpi) throws IOException { final ImageBuilder imageBuilder = ImageBuilder.buildA(new ColorMapperIdentity(), false, null, metadata, null, 1.0, HColorUtils.WHITE); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java index 0f8db89ad..30f2b5609 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -45,9 +45,6 @@ import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; -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.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexOptional; @@ -58,10 +55,10 @@ import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.LinkArrow; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; +import net.sourceforge.plantuml.descdiagram.command.Labels; import net.sourceforge.plantuml.graphic.color.ColorParser; import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; @@ -198,67 +195,11 @@ final public class CommandLinkClass extends SingleLineCommand2".equals(labelLink)) { - linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = null; - } else if (labelLink != null && labelLink.startsWith("< ")) { - linkArrow = LinkArrow.BACKWARD; - labelLink = StringUtils.trin(labelLink.substring(2)); - } else if (labelLink != null && labelLink.startsWith("> ")) { - linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = StringUtils.trin(labelLink.substring(2)); - } else if (labelLink != null && labelLink.endsWith(" >")) { - linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = StringUtils.trin(labelLink.substring(0, labelLink.length() - 2)); - } else if (labelLink != null && labelLink.endsWith(" <")) { - linkArrow = LinkArrow.BACKWARD; - labelLink = StringUtils.trin(labelLink.substring(0, labelLink.length() - 2)); - } - - Link link = new Link(cl1, cl2, linkType, Display.getWithNewlines(labelLink), queue, firstLabel, secondLabel, - diagram.getLabeldistance(), diagram.getLabelangle(), diagram.getSkinParam().getCurrentStyleBuilder()); + Link link = new Link(cl1, cl2, linkType, labels.getDisplay(), queue, labels.getFirstLabel(), + labels.getSecondLabel(), diagram.getLabeldistance(), diagram.getLabelangle(), + diagram.getSkinParam().getCurrentStyleBuilder()); if (arg.get("URL", 0) != null) { final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), ModeUrl.STRICT); final Url url = urlBuilder.getUrl(arg.get("URL", 0)); @@ -269,7 +210,7 @@ final public class CommandLinkClass extends SingleLineCommand2@startfoo and end with - * @endfoo. + * Represents the textual source of some diagram. The source should start with a + * @startfoo and end with @endfoo. *

* So the diagram does not have to be a UML one. * @@ -64,6 +64,7 @@ import net.sourceforge.plantuml.version.IteratorCounter2Impl; final public class UmlSource { final private List source; + final private List rawSource; public UmlSource removeInitialSkinparam() { if (hasInitialSkinparam(source) == false) { @@ -73,7 +74,7 @@ final public class UmlSource { while (hasInitialSkinparam(copy)) { copy.remove(1); } - return new UmlSource(copy); + return new UmlSource(copy, rawSource); } public boolean containsIgnoreCase(String searched) { @@ -86,23 +87,29 @@ final public class UmlSource { } private static boolean hasInitialSkinparam(final List copy) { - return copy.size() > 1 && (copy.get(1).getString().startsWith("skinparam ") || copy.get(1).getString().startsWith("skinparamlocked ")); + return copy.size() > 1 && (copy.get(1).getString().startsWith("skinparam ") + || copy.get(1).getString().startsWith("skinparamlocked ")); } - private UmlSource(List source) { + private UmlSource(List source, List rawSource) { this.source = source; + this.rawSource = rawSource; + } + + public UmlSource(List data, boolean checkEndingBackslash) { + this(data, checkEndingBackslash, new ArrayList()); } /** * Build the source from a text. * - * @param data - * the source of the diagram - * @param checkEndingBackslash - * true if an ending backslash means that a line has to be collapsed with the following one. + * @param data the source of the diagram + * @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, List rawSource) { + this(new ArrayList(), rawSource); if (checkEndingBackslash) { final StringBuilder pending = new StringBuilder(); @@ -122,7 +129,8 @@ final public class UmlSource { } /** - * Retrieve the type of the diagram. This is based on the first line @startfoo. + * Retrieve the type of the diagram. This is based on the first line + * @startfoo. * * @return the type of the diagram. */ @@ -154,6 +162,16 @@ final public class UmlSource { return sb.toString(); } + public String getRawString() { + final StringBuilder sb = new StringBuilder(); + for (StringLocated s : rawSource) { + sb.append(s.getString()); + sb.append('\r'); + sb.append(BackSlash.CHAR_NEWLINE); + } + return sb.toString(); + } + public long seed() { long h = 1125899906842597L; // prime final String string = getPlainString(); @@ -184,7 +202,8 @@ final public class UmlSource { } /** - * Check if a source diagram description is empty. Does not take comment line into account. + * Check if a source diagram description is empty. Does not take comment line + * into account. * * @return true if the diagram does not contain information. */ @@ -207,7 +226,8 @@ final public class UmlSource { } /** - * Retrieve the title, if defined in the diagram source. Never return null. + * Retrieve the title, if defined in the diagram source. Never return + * null. * * @return */ diff --git a/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java b/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java index 28480379c..91b97bab7 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java +++ b/src/net/sourceforge/plantuml/creole/CreoleHorizontalLine.java @@ -83,7 +83,8 @@ public class CreoleHorizontalLine extends AbstractAtom implements Atom { if (line.length() == 0) { return TextBlockUtils.empty(0, 0); } - final CreoleParser parser = new CreoleParser(fontConfiguration, HorizontalAlignment.LEFT, skinParam, CreoleMode.FULL); + final SheetBuilder parser = Parser.build(fontConfiguration, HorizontalAlignment.LEFT, skinParam, + CreoleMode.FULL); final Sheet sheet = parser.createSheet(Display.getWithNewlines(line)); final TextBlock tb = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()); return tb; @@ -107,5 +108,5 @@ public class CreoleHorizontalLine extends AbstractAtom implements Atom { public double getStartingAltitude(StringBounder stringBounder) { return 0; } - + } diff --git a/src/net/sourceforge/plantuml/creole/Fission.java b/src/net/sourceforge/plantuml/creole/Fission.java index fc21f3b43..1cbe796c8 100644 --- a/src/net/sourceforge/plantuml/creole/Fission.java +++ b/src/net/sourceforge/plantuml/creole/Fission.java @@ -45,7 +45,7 @@ import java.util.List; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.creole.atom.AbstractAtom; import net.sourceforge.plantuml.creole.atom.Atom; -import net.sourceforge.plantuml.creole.atom.AtomText; +import net.sourceforge.plantuml.creole.legacy.AtomText; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -70,7 +70,7 @@ public class Fission { return Arrays.asList(stripe); } final List result = new ArrayList(); - StripeSimple current = new StripeSimple(stripe.getHeader()); + StripeSimpleInternal current = new StripeSimpleInternal(stripe.getLHeader()); double remainingSpace = valueMaxWidth; for (Atom atom : noHeader()) { while (true) { @@ -81,7 +81,7 @@ public class Fission { remainingSpace -= widthPart1; if (remainingSpace <= 0) { result.add(current); - current = new StripeSimple(blank(stripe.getHeader())); + current = new StripeSimpleInternal(blank(stripe.getLHeader())); remainingSpace = valueMaxWidth; } if (splitInTwo.size() == 1) { @@ -91,7 +91,7 @@ public class Fission { if (remainingSpace < valueMaxWidth && atom.calculateDimension(stringBounder).getWidth() > remainingSpace) { result.add(current); - current = new StripeSimple(blank(stripe.getHeader())); + current = new StripeSimpleInternal(blank(stripe.getLHeader())); remainingSpace = valueMaxWidth; } } @@ -110,13 +110,13 @@ public class Fission { return Arrays.asList(stripe); } final List result = new ArrayList(); - StripeSimple current = new StripeSimple(stripe.getHeader()); + StripeSimpleInternal current = new StripeSimpleInternal(stripe.getLHeader()); for (Atom atom : noHeader()) { for (Atom atomSplitted : getSplitted(stringBounder, atom)) { final double width = atomSplitted.calculateDimension(stringBounder).getWidth(); if (current.totalWidth + width > valueMaxWidth) { result.add(current); - current = new StripeSimple(blank(stripe.getHeader())); + current = new StripeSimpleInternal(blank(stripe.getLHeader())); } current.addAtom(atomSplitted, width); } @@ -129,7 +129,7 @@ public class Fission { private List noHeader() { final List atoms = stripe.getAtoms(); - if (stripe.getHeader() == null) { + if (stripe.getLHeader() == null) { return atoms; } return atoms.subList(1, atoms.size()); @@ -162,21 +162,12 @@ public class Fission { return Collections.singleton(atom); } - // private List getSplittedSimple() { - // final StripeSimple result = new StripeSimple(); - // for (Atom atom : stripe.getAtoms1()) { - // result.addAtom(atom, 0); - // - // } - // return Arrays.asList((Stripe) result); - // } - - static class StripeSimple implements Stripe { + static class StripeSimpleInternal implements Stripe { private final List atoms = new ArrayList(); private double totalWidth; - private StripeSimple(Atom header) { + private StripeSimpleInternal(Atom header) { if (header != null) { this.atoms.add(header); } @@ -191,7 +182,7 @@ public class Fission { this.totalWidth += width; } - public Atom getHeader() { + public Atom getLHeader() { return null; } diff --git a/src/net/sourceforge/plantuml/creole/Parser.java b/src/net/sourceforge/plantuml/creole/Parser.java new file mode 100644 index 000000000..469b85195 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/Parser.java @@ -0,0 +1,90 @@ +/* ======================================================================== + * 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.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.creole.legacy.CreoleParser; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; + +public class Parser { + + public static final String MONOSPACED = "monospaced"; + + public static SheetBuilder build(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, + ISkinSimple skinParam, CreoleMode creoleMode) { + final FontConfiguration stereotype = fontConfiguration.forceFont(null, null); + return new CreoleParser(fontConfiguration, horizontalAlignment, skinParam, creoleMode, stereotype); + } + + public static SheetBuilder build(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, + ISkinSimple skinParam, CreoleMode creoleMode, FontConfiguration stereotype) { + return new CreoleParser(fontConfiguration, horizontalAlignment, skinParam, creoleMode, stereotype); + } + + public static boolean isTreeStart(String line) { + // return false; + return line.startsWith("|_"); + } + + public static double getScale(String s, double def) { + if (s == null) { + return def; + } + final Pattern p = Pattern.compile("(?:scale=|\\*)([0-9.]+)"); + final Matcher m = p.matcher(s); + if (m.find()) { + return Double.parseDouble(m.group(1)); + } + return def; + } + + public static String getColor(String s) { + if (s == null) { + return null; + } + final Pattern p = Pattern.compile("color[= :](#[0-9a-fA-F]{6}|\\w+)"); + final Matcher m = p.matcher(s); + if (m.find()) { + return m.group(1); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/Sheet.java b/src/net/sourceforge/plantuml/creole/Sheet.java index 44aa5007d..2451ed8e4 100644 --- a/src/net/sourceforge/plantuml/creole/Sheet.java +++ b/src/net/sourceforge/plantuml/creole/Sheet.java @@ -49,7 +49,7 @@ public class Sheet implements Iterable { public Sheet(HorizontalAlignment horizontalAlignment) { this.horizontalAlignment = horizontalAlignment; } - + @Override public String toString() { return stripes.toString(); diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock1.java b/src/net/sourceforge/plantuml/creole/SheetBlock1.java index 73b079cbd..5d4f76042 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock1.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock1.java @@ -45,6 +45,7 @@ import java.util.Map; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.creole.atom.Atom; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.InnerStrategy; diff --git a/src/net/sourceforge/plantuml/creole/SheetBuilder.java b/src/net/sourceforge/plantuml/creole/SheetBuilder.java new file mode 100644 index 000000000..34bb5a0aa --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/SheetBuilder.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole; + +import net.sourceforge.plantuml.cucadiagram.Display; + +public interface SheetBuilder { + + public Sheet createSheet(Display display); + +} diff --git a/src/net/sourceforge/plantuml/creole/Stripe.java b/src/net/sourceforge/plantuml/creole/Stripe.java index ccbd039a9..0c335b329 100644 --- a/src/net/sourceforge/plantuml/creole/Stripe.java +++ b/src/net/sourceforge/plantuml/creole/Stripe.java @@ -41,8 +41,8 @@ import net.sourceforge.plantuml.creole.atom.Atom; public interface Stripe { - public Atom getHeader(); - + public Atom getLHeader(); + public List getAtoms(); } diff --git a/src/net/sourceforge/plantuml/creole/StripeStyle.java b/src/net/sourceforge/plantuml/creole/StripeStyle.java index 53107ca63..521a3ce87 100644 --- a/src/net/sourceforge/plantuml/creole/StripeStyle.java +++ b/src/net/sourceforge/plantuml/creole/StripeStyle.java @@ -36,8 +36,8 @@ package net.sourceforge.plantuml.creole; import net.sourceforge.plantuml.creole.atom.Atom; -import net.sourceforge.plantuml.creole.atom.AtomText; import net.sourceforge.plantuml.creole.atom.Bullet; +import net.sourceforge.plantuml.creole.legacy.AtomText; import net.sourceforge.plantuml.graphic.FontConfiguration; public class StripeStyle { diff --git a/src/net/sourceforge/plantuml/creole/UCreole.java b/src/net/sourceforge/plantuml/creole/UCreole.java index ef9f5d5d9..c82fbadd8 100644 --- a/src/net/sourceforge/plantuml/creole/UCreole.java +++ b/src/net/sourceforge/plantuml/creole/UCreole.java @@ -37,6 +37,5 @@ package net.sourceforge.plantuml.creole; import net.sourceforge.plantuml.ugraphic.UShape; - public interface UCreole extends UShape { } diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomImg.java b/src/net/sourceforge/plantuml/creole/atom/AtomImg.java index f3912f0b2..d27873fd5 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomImg.java +++ b/src/net/sourceforge/plantuml/creole/atom/AtomImg.java @@ -53,6 +53,7 @@ import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.FileUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.code.Base64Coder; +import net.sourceforge.plantuml.creole.legacy.AtomText; import net.sourceforge.plantuml.flashcode.FlashCodeFactory; import net.sourceforge.plantuml.flashcode.FlashCodeUtils; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -195,7 +196,7 @@ public class AtomImg extends AbstractAtom implements Atom { } ug.draw(new UImage(rawFileName, image).scale(scale)); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomOpenIcon.java b/src/net/sourceforge/plantuml/creole/atom/AtomOpenIcon.java index 181e6dba0..0d3e3f5fc 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomOpenIcon.java +++ b/src/net/sourceforge/plantuml/creole/atom/AtomOpenIcon.java @@ -79,7 +79,7 @@ public class AtomOpenIcon extends AbstractAtom implements Atom { } asTextBlock().drawU(ug); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomSprite.java b/src/net/sourceforge/plantuml/creole/atom/AtomSprite.java index 04a8c0cd1..9b79a78c4 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomSprite.java +++ b/src/net/sourceforge/plantuml/creole/atom/AtomSprite.java @@ -72,7 +72,7 @@ public class AtomSprite extends AbstractAtom implements Atom { } sprite.asTextBlock(color, scale).drawU(ug); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomTable.java b/src/net/sourceforge/plantuml/creole/atom/AtomTable.java index 7cef7efc2..7ae2a3cbc 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomTable.java +++ b/src/net/sourceforge/plantuml/creole/atom/AtomTable.java @@ -107,8 +107,8 @@ public class AtomTable extends AbstractAtom implements Atom { final double y2 = getStartingY(i + 1); final double x1 = getStartingX(0); final double x2 = getStartingX(getNbCols()); - ug.apply(new HColorNone()).apply(line.lineBackColor.bg()) - .apply(new UTranslate(x1, y1)).draw(new URectangle(x2 - x1, y2 - y1)); + ug.apply(new HColorNone()).apply(line.lineBackColor.bg()).apply(new UTranslate(x1, y1)) + .draw(new URectangle(x2 - x1, y2 - y1)); } for (int j = 0; j < getNbCols(); j++) { if (j >= line.cells.size()) { @@ -126,8 +126,8 @@ public class AtomTable extends AbstractAtom implements Atom { if (cellBackColor != null) { final double y1 = getStartingY(i); final double y2 = getStartingY(i + 1); - ug.apply(new HColorNone()).apply(cellBackColor.bg()) - .apply(new UTranslate(x1, y1)).draw(new URectangle(x2 - x1, y2 - y1)); + ug.apply(new HColorNone()).apply(cellBackColor.bg()).apply(new UTranslate(x1, y1)) + .draw(new URectangle(x2 - x1, y2 - y1)); } final Position pos = positions.get(cell); final Dimension2D dimCell = cell.calculateDimension(ug.getStringBounder()); diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomTree.java b/src/net/sourceforge/plantuml/creole/atom/AtomTree.java index 3b5504671..a2a0dc86f 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomTree.java +++ b/src/net/sourceforge/plantuml/creole/atom/AtomTree.java @@ -54,7 +54,7 @@ public class AtomTree extends AbstractAtom implements Atom { private final List cells = new ArrayList(); private final Map levels = new HashMap(); private final double margin = 2; - + public AtomTree(HColor lineColor) { this.lineColor = lineColor; } @@ -99,5 +99,5 @@ public class AtomTree extends AbstractAtom implements Atom { this.cells.add(cell); this.levels.put(cell, level); } - + } diff --git a/src/net/sourceforge/plantuml/creole/atom/Bullet.java b/src/net/sourceforge/plantuml/creole/atom/Bullet.java index 3df9c0dbd..e8ac49e34 100644 --- a/src/net/sourceforge/plantuml/creole/atom/Bullet.java +++ b/src/net/sourceforge/plantuml/creole/atom/Bullet.java @@ -104,6 +104,5 @@ public class Bullet extends AbstractAtom implements Atom { private Dimension2D calculateDimension1(StringBounder stringBounder) { return new Dimension2DDouble(getWidth(stringBounder), 3); } - } diff --git a/src/net/sourceforge/plantuml/creole/command/Command.java b/src/net/sourceforge/plantuml/creole/command/Command.java index 5c8f87b54..cd668b0e4 100644 --- a/src/net/sourceforge/plantuml/creole/command/Command.java +++ b/src/net/sourceforge/plantuml/creole/command/Command.java @@ -35,11 +35,11 @@ */ package net.sourceforge.plantuml.creole.command; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; public interface Command { - + public int matchingSize(String line); - + public String executeAndGetRemaining(String line, StripeSimple stripe); } diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorAndSizeChange.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorAndSizeChange.java index ca2c3a0d6..58ca24be8 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorAndSizeChange.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorAndSizeChange.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorChange.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorChange.java index 495f6b8aa..001e54516 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorChange.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleColorChange.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.ugraphic.color.HColor; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleExposantChange.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleExposantChange.java index 5c86e93f6..b2e3cfc29 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleExposantChange.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleExposantChange.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontPosition; @@ -53,12 +53,14 @@ public class CommandCreoleExposantChange implements Command { } public static Command create(FontPosition position) { - return new CommandCreoleExposantChange("^(?i)(" + "\\<" + position.getHtmlTag() + "\\>" + "(.*?)\\)", position); + return new CommandCreoleExposantChange( + "^(?i)(" + "\\<" + position.getHtmlTag() + "\\>" + "(.*?)\\)", + position); } // public static Command createLegacyEol(FontStyle style) { - // return new CommandCreoleExposantChange("^(" + style.getActivationPattern() + "(.+))$", style); + // return new CommandCreoleExposantChange("^(" + style.getActivationPattern() + + // "(.+))$", style); // } public int matchingSize(String line) { diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleFontFamilyChange.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleFontFamilyChange.java index 55fbe1bb6..de06d6390 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleFontFamilyChange.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleFontFamilyChange.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.Splitter; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleImg.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleImg.java index c41b92560..08d427d9e 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleImg.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleImg.java @@ -35,14 +35,12 @@ */ package net.sourceforge.plantuml.creole.command; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.Splitter; public class CommandCreoleImg implements Command { @@ -71,7 +69,7 @@ public class CommandCreoleImg implements Command { throw new IllegalStateException(); } String src = m.group(2); - final double scale = getScale(m.group(3), 1); + final double scale = Parser.getScale(m.group(3), 1); if (src.toLowerCase().startsWith("src=")) { src = src.substring(4); } @@ -80,28 +78,4 @@ public class CommandCreoleImg implements Command { return line.substring(m.group(1).length()); } - public static double getScale(String s, double def) { - if (s == null) { - return def; - } - final Pattern p = Pattern.compile("(?:scale=|\\*)([0-9.]+)"); - final Matcher m = p.matcher(s); - if (m.find()) { - return Double.parseDouble(m.group(1)); - } - return def; - } - - public static String getColor(String s) { - if (s == null) { - return null; - } - final Pattern p = Pattern.compile("color[= :](#[0-9a-fA-F]{6}|\\w+)"); - final Matcher m = p.matcher(s); - if (m.find()) { - return m.group(1); - } - return null; - } - } diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java index 185494b3f..80ed579fa 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleLatex.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.math.ScientificEquationSafe; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleMath.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleMath.java index 27ad87fad..7de5a9eb5 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleMath.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleMath.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.math.ScientificEquationSafe; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleMonospaced.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleMonospaced.java index d5b46f2a5..9a88e56d3 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleMonospaced.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleMonospaced.java @@ -38,13 +38,11 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; public class CommandCreoleMonospaced implements Command { - public static final String MONOSPACED = "monospaced"; - private final Pattern2 pattern; private final String monospacedFamily; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleOpenIcon.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleOpenIcon.java index 74fe4e281..15024218e 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleOpenIcon.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleOpenIcon.java @@ -38,7 +38,8 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; @@ -71,8 +72,8 @@ public class CommandCreoleOpenIcon implements Command { throw new IllegalStateException(); } final String src = m.group(2); - final double scale = CommandCreoleImg.getScale(m.group(3), 1); - final String colorName = CommandCreoleImg.getColor(m.group(3)); + final double scale = Parser.getScale(m.group(3), 1); + final String colorName = Parser.getColor(m.group(3)); HColor color = null; if (colorName != null) { color = colorSet.getColorIfValid(colorName); diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleQrcode.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleQrcode.java index 8160ce0e0..81de72ab1 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleQrcode.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleQrcode.java @@ -38,7 +38,8 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.Splitter; public class CommandCreoleQrcode implements Command { @@ -67,7 +68,7 @@ public class CommandCreoleQrcode implements Command { throw new IllegalStateException(); } final String src = m.group(2); - final double scale = CommandCreoleImg.getScale(m.group(3), 3); + final double scale = Parser.getScale(m.group(3), 3); stripe.addQrcode(src, scale); return line.substring(m.group(1).length()); } diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSizeChange.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSizeChange.java index b1289f931..6cb87d27e 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSizeChange.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSizeChange.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.Splitter; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSpace.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSpace.java index b667c2492..492c4c606 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSpace.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSpace.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; public class CommandCreoleSpace implements Command { diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSprite.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSprite.java index dbed01ccc..9b95331e7 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSprite.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSprite.java @@ -38,7 +38,8 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; @@ -71,8 +72,8 @@ public class CommandCreoleSprite implements Command { throw new IllegalStateException(); } final String src = m.group(2); - final double scale = CommandCreoleImg.getScale(m.group(3), 1); - final String colorName = CommandCreoleImg.getColor(m.group(3)); + final double scale = Parser.getScale(m.group(3), 1); + final String colorName = Parser.getColor(m.group(3)); HColor color = null; if (colorName != null) { color = colorSet.getColorIfValid(colorName); diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleStyle.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleStyle.java index 7cff02729..3a03ab8bc 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleStyle.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleStyle.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.AddStyle; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontStyle; @@ -56,8 +56,9 @@ public class CommandCreoleStyle implements Command { } public static Command createLegacy(FontStyle style) { - return new CommandCreoleStyle("^((" + style.getActivationPattern() + ")(.+?)" + style.getDeactivationPattern() - + ")", style, style.canHaveExtendedColor()); + return new CommandCreoleStyle( + "^((" + style.getActivationPattern() + ")(.+?)" + style.getDeactivationPattern() + ")", style, + style.canHaveExtendedColor()); } public static Command createLegacyEol(FontStyle style) { diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSvgAttributeChange.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSvgAttributeChange.java index 68e62d76d..39be99197 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleSvgAttributeChange.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleSvgAttributeChange.java @@ -38,7 +38,7 @@ package net.sourceforge.plantuml.creole.command; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.graphic.SvgAttributes; diff --git a/src/net/sourceforge/plantuml/creole/command/CommandCreoleUrl.java b/src/net/sourceforge/plantuml/creole/command/CommandCreoleUrl.java index da90515af..83332f4a8 100644 --- a/src/net/sourceforge/plantuml/creole/command/CommandCreoleUrl.java +++ b/src/net/sourceforge/plantuml/creole/command/CommandCreoleUrl.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.UrlBuilder.ModeUrl; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.creole.StripeSimple; +import net.sourceforge.plantuml.creole.legacy.StripeSimple; public class CommandCreoleUrl implements Command { diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomText.java b/src/net/sourceforge/plantuml/creole/legacy/AtomText.java similarity index 95% rename from src/net/sourceforge/plantuml/creole/atom/AtomText.java rename to src/net/sourceforge/plantuml/creole/legacy/AtomText.java index e1119ae53..ec704f267 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomText.java +++ b/src/net/sourceforge/plantuml/creole/legacy/AtomText.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole.atom; +package net.sourceforge.plantuml.creole.legacy; import java.awt.font.LineMetrics; import java.awt.geom.Dimension2D; @@ -53,7 +53,14 @@ import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; -import net.sourceforge.plantuml.creole.command.CommandCreoleImg; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.atom.AbstractAtom; +import net.sourceforge.plantuml.creole.atom.Atom; +import net.sourceforge.plantuml.creole.atom.AtomHorizontalTexts; +import net.sourceforge.plantuml.creole.atom.AtomImg; +import net.sourceforge.plantuml.creole.atom.AtomOpenIcon; +import net.sourceforge.plantuml.creole.atom.AtomSprite; +import net.sourceforge.plantuml.creole.atom.AtomVerticalTexts; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.ImgValign; @@ -124,17 +131,17 @@ public class AtomText extends AbstractAtom implements Atom { if (valOpenicon != null) { final OpenIcon openIcon = OpenIcon.retrieve(valOpenicon); if (openIcon != null) { - final double scale = CommandCreoleImg.getScale(m.group(2), 1); + final double scale = Parser.getScale(m.group(2), 1); result.add(new AtomOpenIcon(null, scale, openIcon, fontConfiguration, url)); } } else if (valSprite != null) { final Sprite sprite = skinSimple.getSprite(valSprite); if (sprite != null) { - final double scale = CommandCreoleImg.getScale(m.group(4), 1); + final double scale = Parser.getScale(m.group(4), 1); result.add(new AtomSprite(null, scale, fontConfiguration, sprite, url)); } } else if (valImg != null) { - final double scale = CommandCreoleImg.getScale(m.group(6), 1); + final double scale = Parser.getScale(m.group(6), 1); result.add(AtomImg.create(valImg, ImgValign.TOP, 0, scale, url)); } @@ -271,7 +278,7 @@ public class AtomText extends AbstractAtom implements Atom { } } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/creole/CreoleParser.java b/src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java similarity index 84% rename from src/net/sourceforge/plantuml/creole/CreoleParser.java rename to src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java index f4f99c889..8ead08824 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleParser.java +++ b/src/net/sourceforge/plantuml/creole/legacy/CreoleParser.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import java.util.Arrays; import java.util.List; @@ -41,28 +41,29 @@ import java.util.List; import net.sourceforge.plantuml.EmbeddedDiagram; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.creole.CreoleContext; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.Sheet; +import net.sourceforge.plantuml.creole.SheetBuilder; +import net.sourceforge.plantuml.creole.Stripe; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; -public class CreoleParser { +public class CreoleParser implements SheetBuilder { private final FontConfiguration fontConfiguration; private final ISkinSimple skinParam; private final HorizontalAlignment horizontalAlignment; private final CreoleMode creoleMode; - private final FontConfiguration stereotypeConfiguration; + private final FontConfiguration stereotype; public CreoleParser(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple skinParam, CreoleMode creoleMode) { - this(fontConfiguration, horizontalAlignment, skinParam, creoleMode, fontConfiguration.forceFont(null, null)); - } - - public CreoleParser(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple skinParam, CreoleMode creoleMode, FontConfiguration stereotypeConfiguration) { - this.stereotypeConfiguration = stereotypeConfiguration; + ISkinSimple skinParam, CreoleMode creoleMode, FontConfiguration stereotype) { + this.stereotype = stereotype; this.creoleMode = creoleMode; this.fontConfiguration = fontConfiguration; this.skinParam = skinParam; @@ -78,13 +79,13 @@ public class CreoleParser { final StripeTable table = (StripeTable) lastStripe; table.analyzeAndAddLine(line); return null; - } else if (lastStripe instanceof StripeTree && isTreeStart(StringUtils.trinNoTrace(line))) { + } else if (lastStripe instanceof StripeTree && Parser.isTreeStart(StringUtils.trinNoTrace(line))) { final StripeTree tree = (StripeTree) lastStripe; tree.analyzeAndAdd(line); return null; } else if (isTableLine(line)) { return new StripeTable(fontConfiguration, skinParam, line); - } else if (isTreeStart(line)) { + } else if (Parser.isTreeStart(line)) { return new StripeTree(fontConfiguration, skinParam, line); } return new CreoleStripeSimpleParser(line, context, fontConfiguration, skinParam, creoleMode) @@ -99,11 +100,6 @@ public class CreoleParser { return line.matches("^\\=?\\s*(\\<#\\w+(,#?\\w+)?\\>).*"); } - public static boolean isTreeStart(String line) { - // return false; - return line.startsWith("|_"); - } - public Sheet createSheet(Display display) { final Sheet sheet = new Sheet(horizontalAlignment); if (Display.isNull(display) == false) { @@ -113,7 +109,7 @@ public class CreoleParser { if (cs instanceof EmbeddedDiagram) { final Atom atom = ((EmbeddedDiagram) cs).asDraw(skinParam); stripe = new Stripe() { - public Atom getHeader() { + public Atom getLHeader() { return null; } @@ -123,7 +119,7 @@ public class CreoleParser { }; } else if (cs instanceof Stereotype) { for (String st : ((Stereotype) cs).getLabels(skinParam.guillemet())) { - sheet.add(createStripe(st, context, sheet.getLastStripe(), stereotypeConfiguration)); + sheet.add(createStripe(st, context, sheet.getLastStripe(), stereotype)); } continue; } else { diff --git a/src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java b/src/net/sourceforge/plantuml/creole/legacy/CreoleStripeSimpleParser.java similarity index 94% rename from src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java rename to src/net/sourceforge/plantuml/creole/legacy/CreoleStripeSimpleParser.java index 789e8e394..841cab5ee 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java +++ b/src/net/sourceforge/plantuml/creole/legacy/CreoleStripeSimpleParser.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.ISkinSimple; @@ -41,6 +41,11 @@ import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; +import net.sourceforge.plantuml.creole.CreoleContext; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Stripe; +import net.sourceforge.plantuml.creole.StripeStyle; +import net.sourceforge.plantuml.creole.StripeStyleType; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.utils.CharHidder; diff --git a/src/net/sourceforge/plantuml/creole/PSystemCreole.java b/src/net/sourceforge/plantuml/creole/legacy/PSystemCreole.java similarity index 86% rename from src/net/sourceforge/plantuml/creole/PSystemCreole.java rename to src/net/sourceforge/plantuml/creole/legacy/PSystemCreole.java index 887bfc512..c505b9d85 100644 --- a/src/net/sourceforge/plantuml/creole/PSystemCreole.java +++ b/src/net/sourceforge/plantuml/creole/legacy/PSystemCreole.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import java.io.IOException; import java.io.OutputStream; @@ -47,6 +47,10 @@ import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Parser; +import net.sourceforge.plantuml.creole.Sheet; +import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -75,17 +79,17 @@ public class PSystemCreole extends AbstractPSystem { final Display display = Display.create(lines); final UFont font = UFont.serif(14); final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(font); - final Sheet sheet = new CreoleParser(fontConfiguration, HorizontalAlignment.LEFT, SkinParam.create(UmlDiagramType.SEQUENCE), CreoleMode.FULL) - .createSheet(display); + final Sheet sheet = Parser.build(fontConfiguration, HorizontalAlignment.LEFT, + SkinParam.create(UmlDiagramType.SEQUENCE), CreoleMode.FULL).createSheet(display); final SheetBlock1 sheetBlock = new SheetBlock1(sheet, LineBreakStrategy.NONE, 0); - final ImageBuilder builder = ImageBuilder.buildA(new ColorMapperIdentity(), false, null, null, null, 1.0, - null); + final ImageBuilder builder = ImageBuilder.buildA(new ColorMapperIdentity(), false, null, null, null, 1.0, null); builder.setUDrawable(sheetBlock); return builder.writeImageTOBEMOVED(fileFormat, seed, os); // final Dimension2D dim = TextBlockUtils.getDimension(sheetBlock); - // final UGraphic2 ug = fileFormat.createUGraphic(new ColorMapperIdentity(), 1, dim, null, false); + // final UGraphic2 ug = fileFormat.createUGraphic(new ColorMapperIdentity(), 1, + // dim, null, false); // // sheetBlock.drawU(ug.apply(UTranslate.dy(10))); // sheetBlock.drawU(ug); // ug.writeImageTOBEMOVED(os, null, 96); diff --git a/src/net/sourceforge/plantuml/creole/PSystemCreoleFactory.java b/src/net/sourceforge/plantuml/creole/legacy/PSystemCreoleFactory.java similarity index 97% rename from src/net/sourceforge/plantuml/creole/PSystemCreoleFactory.java rename to src/net/sourceforge/plantuml/creole/legacy/PSystemCreoleFactory.java index 5543c5b4b..42be17322 100644 --- a/src/net/sourceforge/plantuml/creole/PSystemCreoleFactory.java +++ b/src/net/sourceforge/plantuml/creole/legacy/PSystemCreoleFactory.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import net.sourceforge.plantuml.command.PSystemBasicFactory; import net.sourceforge.plantuml.core.DiagramType; diff --git a/src/net/sourceforge/plantuml/creole/StripeSimple.java b/src/net/sourceforge/plantuml/creole/legacy/StripeSimple.java similarity index 96% rename from src/net/sourceforge/plantuml/creole/StripeSimple.java rename to src/net/sourceforge/plantuml/creole/legacy/StripeSimple.java index 60863765d..42a1d1733 100644 --- a/src/net/sourceforge/plantuml/creole/StripeSimple.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeSimple.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import java.util.ArrayList; import java.util.Collections; @@ -42,13 +42,18 @@ import java.util.List; import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.creole.CreoleContext; +import net.sourceforge.plantuml.creole.CreoleHorizontalLine; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Stripe; +import net.sourceforge.plantuml.creole.StripeStyle; +import net.sourceforge.plantuml.creole.StripeStyleType; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.creole.atom.AtomImg; import net.sourceforge.plantuml.creole.atom.AtomMath; import net.sourceforge.plantuml.creole.atom.AtomOpenIcon; import net.sourceforge.plantuml.creole.atom.AtomSpace; import net.sourceforge.plantuml.creole.atom.AtomSprite; -import net.sourceforge.plantuml.creole.atom.AtomText; import net.sourceforge.plantuml.creole.command.Command; import net.sourceforge.plantuml.creole.command.CommandCreoleColorAndSizeChange; import net.sourceforge.plantuml.creole.command.CommandCreoleColorChange; @@ -103,7 +108,7 @@ public class StripeSimple implements Stripe { return super.toString() + " " + atoms.toString(); } - public Atom getHeader() { + public Atom getLHeader() { return header; } diff --git a/src/net/sourceforge/plantuml/creole/StripeTable.java b/src/net/sourceforge/plantuml/creole/legacy/StripeTable.java similarity index 93% rename from src/net/sourceforge/plantuml/creole/StripeTable.java rename to src/net/sourceforge/plantuml/creole/legacy/StripeTable.java index a06b83f34..f62b442e1 100644 --- a/src/net/sourceforge/plantuml/creole/StripeTable.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeTable.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import java.util.ArrayList; import java.util.Collections; @@ -43,6 +43,13 @@ import java.util.StringTokenizer; import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.LineBreakStrategy; +import net.sourceforge.plantuml.creole.CreoleContext; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Sheet; +import net.sourceforge.plantuml.creole.SheetBlock1; +import net.sourceforge.plantuml.creole.Stripe; +import net.sourceforge.plantuml.creole.StripeStyle; +import net.sourceforge.plantuml.creole.StripeStyleType; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.creole.atom.AtomTable; import net.sourceforge.plantuml.creole.atom.AtomWithMargin; @@ -78,7 +85,7 @@ public class StripeTable implements Stripe { return Collections.singletonList(marged); } - public Atom getHeader() { + public Atom getLHeader() { return null; } diff --git a/src/net/sourceforge/plantuml/creole/StripeTree.java b/src/net/sourceforge/plantuml/creole/legacy/StripeTree.java similarity index 88% rename from src/net/sourceforge/plantuml/creole/StripeTree.java rename to src/net/sourceforge/plantuml/creole/legacy/StripeTree.java index edbcd482e..20a5cc023 100644 --- a/src/net/sourceforge/plantuml/creole/StripeTree.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeTree.java @@ -33,12 +33,17 @@ * * */ -package net.sourceforge.plantuml.creole; +package net.sourceforge.plantuml.creole.legacy; import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.creole.CreoleContext; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Stripe; +import net.sourceforge.plantuml.creole.StripeStyle; +import net.sourceforge.plantuml.creole.StripeStyleType; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.creole.atom.AtomTree; import net.sourceforge.plantuml.creole.atom.AtomWithMargin; @@ -61,10 +66,10 @@ public class StripeTree implements Stripe { } public List getAtoms() { - return Collections. singletonList(marged); + return Collections.singletonList(marged); } - public Atom getHeader() { + public Atom getLHeader() { return null; } diff --git a/src/net/sourceforge/plantuml/creole/rosetta/AtomText22.java b/src/net/sourceforge/plantuml/creole/rosetta/AtomText22.java new file mode 100644 index 000000000..1553716db --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/AtomText22.java @@ -0,0 +1,289 @@ +/* ======================================================================== + * 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.rosetta; + +import java.awt.font.LineMetrics; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +import net.sourceforge.plantuml.BackSlash; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.LineBreakStrategy; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.creole.atom.AbstractAtom; +import net.sourceforge.plantuml.creole.atom.Atom; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UText; +import net.sourceforge.plantuml.ugraphic.UTranslate; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.HColorAutomatic; +import net.sourceforge.plantuml.ugraphic.color.HColorSimple; +import net.sourceforge.plantuml.utils.CharHidder; + +public class AtomText22 extends AbstractAtom implements Atom { + + interface DelayedDouble { + public double getDouble(StringBounder stringBounder); + } + + private static DelayedDouble ZERO = new DelayedDouble() { + public double getDouble(StringBounder stringBounder) { + return 0; + } + }; + + private final FontConfiguration fontConfiguration; + private final String text; + private final DelayedDouble marginLeft; + private final DelayedDouble marginRight; + private final Url url; + + public static Atom create(String text, FontConfiguration fontConfiguration) { + return new AtomText22(text, fontConfiguration, null, ZERO, ZERO); + } + + @Override + public String toString() { + return text + " " + fontConfiguration; + } + + private AtomText22(String text, FontConfiguration style, Url url, DelayedDouble marginLeft, + DelayedDouble marginRight) { + if (text.contains("" + BackSlash.hiddenNewLine())) { + throw new IllegalArgumentException(text); + } + this.marginLeft = marginLeft; + this.marginRight = marginRight; + this.text = CharHidder.unhide(text); +// this.text = StringUtils.manageTildeArobaseStart(StringUtils.manageUnicodeNotationUplus( +// StringUtils.manageAmpDiese(StringUtils.showComparatorCharacters(CharHidder.unhide(text))))); + this.fontConfiguration = style; + this.url = url; + } + + public FontConfiguration getFontConfiguration() { + return fontConfiguration; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + final Dimension2D rect = stringBounder.calculateDimension(fontConfiguration.getFont(), text); + Log.debug("g2d=" + rect); + Log.debug("Size for " + text + " is " + rect); + double h = rect.getHeight(); + if (h < 10) { + h = 10; + } + final double width = text.indexOf('\t') == -1 ? rect.getWidth() : getWidth(stringBounder); + final double left = marginLeft.getDouble(stringBounder); + final double right = marginRight.getDouble(stringBounder); + + return new Dimension2DDouble(width + left + right, h); + } + + private double getDescent() { + final LineMetrics fm = TextBlockUtils.getLineMetrics(fontConfiguration.getFont(), text); + final double descent = fm.getDescent(); + return descent; + } + + public double getFontSize2D() { + return fontConfiguration.getFont().getSize2D(); + } + + public double getStartingAltitude(StringBounder stringBounder) { + return fontConfiguration.getSpace(); + } + + private double getTabSize(StringBounder stringBounder) { + return stringBounder.calculateDimension(fontConfiguration.getFont(), tabString()).getWidth(); + } + + private String tabString() { + final int nb = fontConfiguration.getTabSize(); + if (nb >= 1 && nb < 7) { + return " ".substring(0, nb); + } + return " "; + } + + public void drawU(UGraphic ug) { + if (url != null) { + ug.startUrl(url); + } + if (ug.matchesProperty("SPECIALTXT")) { + ug.draw(this); + throw new UnsupportedOperationException("SPECIALTXT"); + } else { + HColor textColor = fontConfiguration.getColor(); + FontConfiguration useFontConfiguration = fontConfiguration; + if (textColor instanceof HColorAutomatic && ug.getParam().getBackcolor() != null) { + textColor = ((HColorSimple) ug.getParam().getBackcolor()).opposite(); + useFontConfiguration = fontConfiguration.changeColor(textColor); + } + if (marginLeft != ZERO) { + ug = ug.apply(UTranslate.dx(marginLeft.getDouble(ug.getStringBounder()))); + } + + final StringTokenizer tokenizer = new StringTokenizer(text, "\t", true); + + double x = 0; + // final int ypos = fontConfiguration.getSpace(); + final Dimension2D rect = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(), text); + final double descent = getDescent(); + final double ypos = rect.getHeight() - descent; + if (tokenizer.hasMoreTokens()) { + final double tabSize = getTabSize(ug.getStringBounder()); + while (tokenizer.hasMoreTokens()) { + final String s = tokenizer.nextToken(); + if (s.equals("\t")) { + final double remainder = x % tabSize; + x += tabSize - remainder; + } else { + final UText utext = new UText(s, useFontConfiguration); + final Dimension2D dim = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(), + s); + ug.apply(new UTranslate(x, ypos)).draw(utext); + x += dim.getWidth(); + } + } + } + } + if (url != null) { + ug.closeUrl(); + } + } + + private double getWidth(StringBounder stringBounder) { + return getWidth(stringBounder, text); + } + + private double getWidth(StringBounder stringBounder, String text) { + final StringTokenizer tokenizer = new StringTokenizer(text, "\t", true); + final double tabSize = getTabSize(stringBounder); + double x = 0; + while (tokenizer.hasMoreTokens()) { + final String s = tokenizer.nextToken(); + if (s.equals("\t")) { + final double remainder = x % tabSize; + x += tabSize - remainder; + } else { + final Dimension2D dim = stringBounder.calculateDimension(fontConfiguration.getFont(), s); + x += dim.getWidth(); + } + } + return x; + } + + public List getSplitted(StringBounder stringBounder, LineBreakStrategy maxWidthAsString) { + final double maxWidth = maxWidthAsString.getMaxWidth(); + if (maxWidth == 0) { + throw new IllegalStateException(); + } + final List result = new ArrayList(); + final StringTokenizer st = new StringTokenizer(text, " ", true); + final StringBuilder currentLine = new StringBuilder(); + while (st.hasMoreTokens()) { + final String token1 = st.nextToken(); + for (String tmp : Arrays.asList(token1)) { + final double w = getWidth(stringBounder, currentLine + tmp); + if (w > maxWidth) { + result.add(new AtomText22(currentLine.toString(), fontConfiguration, url, marginLeft, marginRight)); + currentLine.setLength(0); + if (tmp.startsWith(" ") == false) { + currentLine.append(tmp); + } + } else { + currentLine.append(tmp); + } + } + } + result.add(new AtomText22(currentLine.toString(), fontConfiguration, url, marginLeft, marginRight)); + return Collections.unmodifiableList(result); + + } + + @Override + public List splitInTwo(StringBounder stringBounder, double width) { + final StringBuilder tmp = new StringBuilder(); + for (String token : splitted()) { + if (tmp.length() > 0 && getWidth(stringBounder, tmp.toString() + token) > width) { + final Atom part1 = new AtomText22(tmp.toString(), fontConfiguration, url, marginLeft, marginRight); + String remain = text.substring(tmp.length()); + while (remain.startsWith(" ")) { + remain = remain.substring(1); + } + + final Atom part2 = new AtomText22(remain, fontConfiguration, url, marginLeft, marginRight); + return Arrays.asList(part1, part2); + } + tmp.append(token); + } + return Collections.singletonList((Atom) this); + } + + private Collection splitted() { + final List result = new ArrayList(); + for (int i = 0; i < text.length(); i++) { + final char ch = text.charAt(i); + if (Character.isLetter(ch)) { + final StringBuilder tmp = new StringBuilder(); + tmp.append(ch); + while (i + 1 < text.length() && Character.isLetter(text.charAt(i + 1))) { + i++; + tmp.append(text.charAt(i)); + } + result.add(tmp.toString()); + } else { + result.add("" + text.charAt(i)); + } + } + return result; + } + + public final String getText() { + return text; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/CreoleParser2.java b/src/net/sourceforge/plantuml/creole/rosetta/CreoleParser2.java new file mode 100644 index 000000000..3c7482a76 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/CreoleParser2.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole.rosetta; + +import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.creole.CreoleMode; +import net.sourceforge.plantuml.creole.Sheet; +import net.sourceforge.plantuml.creole.SheetBuilder; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; + +public class CreoleParser2 implements SheetBuilder { + + private final FontConfiguration fontConfiguration; + private final ISkinSimple skinParam; + private final HorizontalAlignment horizontalAlignment; + private final CreoleMode creoleMode; + private final FontConfiguration stereotype; + + public CreoleParser2(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, + ISkinSimple skinParam, CreoleMode creoleMode, FontConfiguration stereotype) { + this.stereotype = stereotype; + this.creoleMode = creoleMode; + this.fontConfiguration = fontConfiguration; + this.skinParam = skinParam; + if (skinParam == null) { + throw new IllegalArgumentException(); + } + this.horizontalAlignment = horizontalAlignment; + } + + public Sheet createSheet(Display display) { + final Sheet sheet = new Sheet(horizontalAlignment); + if (display.isWhite() == false) { + final Rosetta rosetta = Rosetta.fromSyntax(WikiLanguage.CREOLE, display); + for (String cs : rosetta.translateTo(WikiLanguage.UNICODE)) { + final StripeRow row = StripeRow.parseUnicode(cs, fontConfiguration); + sheet.add(row); + } + } + return sheet; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/ReaderAbstractWiki.java b/src/net/sourceforge/plantuml/creole/rosetta/ReaderAbstractWiki.java new file mode 100644 index 000000000..f263e5862 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/ReaderAbstractWiki.java @@ -0,0 +1,105 @@ +package net.sourceforge.plantuml.creole.rosetta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public abstract class ReaderAbstractWiki implements ReaderWiki { + + static protected final String PNG_OR_GIF = "([-_\\w]+\\.(?:png|gif))"; + + static protected final String BRACKET1 = "\\[([^\\[\\]]+?)\\]"; + static protected final String BRACKET0 = "\\[([^\\[\\]]*?)\\]"; + + final public List transform(String... data) { + return transform(Arrays.asList(data)); + } + + // final protected String protectURL(String s) { + // return WikiLanguage.protectURL(s); + // } + + final protected String rawCode(String s, String start, String end) { + final StringBuilder sb = new StringBuilder(s.length()); + boolean rawMode = false; + boolean rawInRaw = false; + for (int i = 0; i < s.length(); i++) { + if (rawMode == false && s.substring(i).startsWith(start)) { + rawMode = true; + rawInRaw = false; + i += start.length() - 1; + sb.append(WikiLanguage.UNICODE.tag("code")); + if (s.substring(i + 1).startsWith(start)) { + i += start.length(); + sb.append(WikiLanguage.hideCharsF7(start)); + rawInRaw = true; + } + continue; + } + if (rawMode == true && s.substring(i).startsWith(end) && s.substring(i + 1).startsWith(end) == false) { + rawMode = false; + i += end.length() - 1; + if (rawInRaw && s.substring(i + 1).startsWith(end)) { + i += end.length(); + sb.append(WikiLanguage.hideCharsF7(end)); + } + sb.append(WikiLanguage.UNICODE.slashTag("code")); + rawInRaw = false; + continue; + } + char ch = s.charAt(i); + if (rawMode) { + ch = WikiLanguage.toF7(ch); + } + sb.append(ch); + } + return sb.toString(); + } + + protected final String cleanAndHideBackslashSeparator(String s, String sep, String unicodeSep) { + s = s.trim(); + if (s.startsWith(sep)) { + s = s.substring(1); + } + if (s.endsWith(sep)) { + s = s.substring(0, s.length() - 1); + } + s = s.trim(); + final String regex; + if (sep.equals("^") || sep.equals("|")) { + regex = "\\\\\\" + sep; + } else { + throw new IllegalArgumentException(); + } + s = s.replaceAll(regex, unicodeSep); + s = singleLineFormat(s.trim()); + s = s.replace(sep, " " + sep + " "); + return s; + } + + protected abstract String singleLineFormat(String wiki); + + final protected void exportCodeInternal(List uhtml, String tag, List lines) { + uhtml.add(WikiLanguage.UNICODE.tag(tag)); + for (String s : lines) { + uhtml.add(s); + } + uhtml.add(WikiLanguage.UNICODE.slashTag(tag)); + } + + final protected void exportCodeInternalEnsureStartuml(List uhtml, String tag, List lines) { + exportCodeInternal(uhtml, tag, ensureStartuml(lines)); + } + + private List ensureStartuml(List lines) { + final String first = lines.get(0); + if (first.startsWith("@start")) { + return lines; + } + final List copy = new ArrayList(lines); + copy.add(0, "@startuml"); + copy.add("@enduml"); + return copy; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/ReaderCreole.java b/src/net/sourceforge/plantuml/creole/rosetta/ReaderCreole.java new file mode 100644 index 000000000..f8d7fb3c3 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/ReaderCreole.java @@ -0,0 +1,40 @@ +package net.sourceforge.plantuml.creole.rosetta; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ReaderCreole extends ReaderAbstractWiki implements ReaderWiki { + + @Override + protected String singleLineFormat(String wiki) { + + // Legacy HTML + wiki = wiki.replace("", WikiLanguage.UNICODE.tag("strong")); + wiki = wiki.replace("", WikiLanguage.UNICODE.slashTag("strong")); + wiki = wiki.replace("", WikiLanguage.UNICODE.tag("em")); + wiki = wiki.replace("", WikiLanguage.UNICODE.slashTag("em")); + + // Em & Strong + wiki = wiki.replaceAll("\\*\\*(.+?)\\*\\*", + WikiLanguage.UNICODE.tag("strong") + "$1" + WikiLanguage.UNICODE.slashTag("strong")); + wiki = wiki.replaceAll("//(.+?)//", + WikiLanguage.UNICODE.tag("em") + "$1" + WikiLanguage.UNICODE.slashTag("em")); + + // Strike + wiki = wiki.replaceAll("--([^-]+?)--", + WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike")); + + return wiki; + } + + public List transform(List raw) { + final List uhtml = new ArrayList(); + for (int i = 0; i < raw.size(); i++) { + String current = raw.get(i); + uhtml.add(singleLineFormat(current)); + } + return Collections.unmodifiableList(uhtml); + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/ReaderDokuwiki.java b/src/net/sourceforge/plantuml/creole/rosetta/ReaderDokuwiki.java new file mode 100644 index 000000000..977ee2c99 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/ReaderDokuwiki.java @@ -0,0 +1,326 @@ +package net.sourceforge.plantuml.creole.rosetta; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ReaderDokuwiki extends ReaderAbstractWiki implements ReaderWiki { + + @Override + protected String singleLineFormat(String wiki) { + final boolean endingSlashSlash = wiki.endsWith("\\\\"); + if (endingSlashSlash) { + wiki = wiki.substring(0, wiki.length() - 2); + } + + // Raw %% and '' + wiki = rawCode(wiki, "''%%", "%%''"); + wiki = rawCode(wiki, "%%", "%%"); + wiki = rawCode(wiki, "''", "''"); + + // Protect/escape some character + for (char c : "^|<".toCharArray()) { + wiki = wiki.replace("\\" + c, "" + WikiLanguage.toF7(c)); + } + + // Horizontal lines + wiki = wiki.replaceAll("^___+$", WikiLanguage.UNICODE.tag("hr")); + wiki = wiki.replaceAll("^---+$", WikiLanguage.UNICODE.tag("hr")); + wiki = wiki.replaceAll("^\\*\\*\\*+$", WikiLanguage.UNICODE.tag("hr")); + + // Strike + wiki = wiki.replaceAll("\\([^<>]+?)\\", + WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike")); + wiki = wiki.replaceAll("\\([^<>]+?)\\", + WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike")); + wiki = wiki.replaceAll("~~([^~]+?)~~", + WikiLanguage.UNICODE.tag("strike") + "$1" + WikiLanguage.UNICODE.slashTag("strike")); + + // break + wiki = wiki.replace("\\\\ ", WikiLanguage.UNICODE.tag("br")); + + // Em & Strong + wiki = wiki.replaceAll("//(.+?)//", + WikiLanguage.UNICODE.tag("em") + "$1" + WikiLanguage.UNICODE.slashTag("em")); + wiki = wiki.replaceAll("\\*\\*(.+?)\\*\\*", + WikiLanguage.UNICODE.tag("strong") + "$1" + WikiLanguage.UNICODE.slashTag("strong")); + wiki = wiki.replace(WikiLanguage.UNICODE.tag("strong") + WikiLanguage.UNICODE.tag("em"), + WikiLanguage.UNICODE.tag("strongem")); + wiki = wiki.replace(WikiLanguage.UNICODE.tag("em") + WikiLanguage.UNICODE.tag("strong"), + WikiLanguage.UNICODE.tag("strongem")); + wiki = wiki.replace(WikiLanguage.UNICODE.slashTag("strong") + WikiLanguage.UNICODE.slashTag("em"), + WikiLanguage.UNICODE.slashTag("strongem")); + wiki = wiki.replace(WikiLanguage.UNICODE.slashTag("em") + WikiLanguage.UNICODE.slashTag("strong"), + WikiLanguage.UNICODE.slashTag("strongem")); + + // Underscore + wiki = wiki.replaceAll("__(.+?)__", WikiLanguage.UNICODE.tag("u") + "$1" + WikiLanguage.UNICODE.slashTag("u")); + + if (endingSlashSlash) { + wiki += WikiLanguage.UNICODE.tag("br"); + } + + return wiki; + } + + public List transform(List raw) { + final List uhtml = new ArrayList(); + for (int i = 0; i < raw.size(); i++) { + String current = raw.get(i); + + if (current.startsWith("FIXME ")) { + continue; + } + + current = current.replaceFirst("^\\s+@start", "@start"); + current = current.replaceFirst("^\\s+@end", "@end"); + + final AutoGroup autoGroup = getAutoGroup(raw, i); + if (autoGroup != null) { + i += autoGroup.getSkipped() - 1; + autoGroup.exportHtml(uhtml); + continue; + } + + final StartEndGroup startEndGroup = getStartEndGroup(raw, i); + if (startEndGroup != null) { + i += startEndGroup.getSkipped() - 1; + startEndGroup.exportHtml(uhtml); + continue; + } + + if (current.length() == 0) { + uhtml.add(WikiLanguage.UNICODE.tag("p")); + } else { + uhtml.add(singleLineFormat(current)); + } + } + return Collections.unmodifiableList(uhtml); + } + + private StartEndGroup getStartEndGroup(List raw, int i) { + if (raw.get(i).equals("")) { + return new StartEndGroup(raw, i, ""); + } + if (raw.get(i).startsWith(""); + } + if (raw.get(i).equals("")) { + return new StartEndGroup(raw, i, ""); + } + return null; + } + + private AutoGroup getAutoGroup(List raw, int i) { + AutoGroup group = getAutoGroup(raw, i, " * ", " * "); + if (group != null) { + return group; + } + group = getAutoGroup(raw, i, " - ", " - "); + if (group != null) { + return group; + } + group = getAutoGroup(raw, i, "\t"); + if (group != null) { + return group; + } + group = getAutoGroup(raw, i, "> "); + if (group != null) { + return group; + } + group = getAutoGroup(raw, i, "] "); + if (group != null) { + return group; + } + group = getAutoGroup(raw, i, " "); + if (group != null) { + return group; + } + group = getAutoGroup(raw, i, "^"); + if (group != null) { + return group; + } + return null; + } + + private AutoGroup getAutoGroup(List raw, int i, String... headers) { + if (raw.get(i).startsWith(headers[0]) == false) { + return null; + } + final AutoGroup result = new AutoGroup(headers); + while (i < raw.size() && result.isInTheGroup(raw.get(i))) { + result.addLine(raw.get(i)); + i++; + } + return result; + } + + class AutoGroup { + + private final List lines = new ArrayList(); + private int skip = 0; + private final String[] headers; + + private AutoGroup(String[] headers) { + this.headers = headers; + } + + private void addLine(String s) { + if (headers[0].equals("> ") && s.equals(">")) { + lines.add(""); + } else if (headers[0].equals("] ") && s.equals("]")) { + lines.add(""); + } else if (headers[0].equals("^")) { + lines.add(s); + } else { + lines.add(s.substring(headers[0].length())); + } + skip++; + } + + private int getSkipped() { + return skip; + } + + private void exportHtml(List uhtml) { + if (headers[0].equals(" * ")) { + exportList(uhtml, "ul"); + } else if (headers[0].equals(" - ")) { + exportList(uhtml, "ol"); + } else if (headers[0].equals(" ")) { + exportCode(uhtml); + } else if (headers[0].equals("\t")) { + exportCode(uhtml); + } else if (headers[0].equals("> ")) { + exportBlockquote(uhtml); + } else if (headers[0].equals("] ")) { + exportFieldset(uhtml); + } else if (headers[0].equals("^")) { + exportTable(uhtml); + } else { + throw new UnsupportedOperationException(); + } + } + + private void exportCode(List uhtml) { + exportCodeInternal(uhtml, "codepre", lines); + } + + private void exportList(List uhtml, String type) { + uhtml.add(WikiLanguage.UNICODE.tag(type)); + for (String s : lines) { + int level = 0; + if (s.startsWith("* ") || s.startsWith("- ")) { + level++; + s = s.substring(2); + } + uhtml.add(WikiLanguage.UNICODE.tag(type + "li", "level", "" + level) + singleLineFormat(s) + + WikiLanguage.UNICODE.slashTag(type + "li")); + } + uhtml.add(WikiLanguage.UNICODE.slashTag(type)); + } + + private void exportFieldset(List uhtml) { + uhtml.add(WikiLanguage.UNICODE.tag("fieldset")); + uhtml.addAll(transform(lines)); + uhtml.add(WikiLanguage.UNICODE.slashTag("fieldset")); + } + + private void exportBlockquote(List uhtml) { + uhtml.add(WikiLanguage.UNICODE.tag("blockquote")); + uhtml.addAll(transform(lines)); + uhtml.add(WikiLanguage.UNICODE.slashTag("blockquote")); + } + + private void exportTable(List uhtml) { + uhtml.add(WikiLanguage.UNICODE.tag("table")); + int i = 0; + int sizeHeader = 0; + for (String s : lines) { + final String sep = i == 0 ? "^" : "|"; + final String tagHeader = i == 0 ? "th" : "tr"; + final String cellHeader = i == 0 ? "tdh" : "td"; + uhtml.add(WikiLanguage.UNICODE.tag(tagHeader)); + + s = cleanAndHideBackslashSeparator(s, sep, "\uF500"); + + final String cols[] = s.split("\\" + sep); + // System.err.println("cols1=" + Arrays.asList(cols)); + if (i == 0) { + sizeHeader = cols.length; + } else if (cols.length != sizeHeader) { + System.err.println("lines=" + lines); + System.err.println("WARNING!!! " + sizeHeader + " " + cols.length); + throw new IllegalStateException("WARNING!!! " + sizeHeader + " " + cols.length); + } + for (String cell : cols) { + cell = cell.trim(); + // if (cell.length() > 0) { + uhtml.add(WikiLanguage.UNICODE.tag(cellHeader)); + // uhtml.add(singleLineFormat(cell)); + uhtml.add(WikiLanguage.restoreAllCharsF7(cell.replace('\uF500', sep.charAt(0)))); + uhtml.add(WikiLanguage.UNICODE.slashTag(cellHeader)); + // } + + } + uhtml.add(WikiLanguage.UNICODE.slashTag(tagHeader)); + i++; + } + uhtml.add(WikiLanguage.UNICODE.slashTag("table")); + } + + public boolean isInTheGroup(String line) { + if (headers[0].equals("^") && line.startsWith("|")) { + return true; + } + if (headers[0].equals("> ") && line.startsWith(">")) { + return true; + } + if (headers[0].equals("] ") && line.startsWith("]")) { + return true; + } + for (String header : headers) { + if (line.startsWith(header)) { + return true; + } + } + return false; + } + } + + class StartEndGroup { + + private final List lines = new ArrayList(); + private int skip = 0; + private final String first; + + private StartEndGroup(List raw, int i, String end) { + this.first = raw.get(i); + skip++; + i++; + while (i < raw.size() && raw.get(i).equals(end) == false) { + lines.add(raw.get(i)); + i++; + skip++; + } + skip++; + } + + private void exportHtml(List uhtml) { + if (first.equals("")) { + exportCodeInternal(uhtml, "codepre", lines); + } else if (first.startsWith("")) { + exportCodeInternalEnsureStartuml(uhtml, "codeandimg", lines); + } else { + throw new UnsupportedOperationException(); + } + } + + private int getSkipped() { + return skip; + } + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/ReaderWiki.java b/src/net/sourceforge/plantuml/creole/rosetta/ReaderWiki.java new file mode 100644 index 000000000..40e907f4d --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/ReaderWiki.java @@ -0,0 +1,11 @@ +package net.sourceforge.plantuml.creole.rosetta; + +import java.util.List; + +public interface ReaderWiki { + + public static final String REGEX_HTTP = "https?://[^\\s/$.?#][^()\\[\\]\\s]*"; + + public List transform(List data); + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/Rosetta.java b/src/net/sourceforge/plantuml/creole/rosetta/Rosetta.java new file mode 100644 index 000000000..bd3a69237 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/Rosetta.java @@ -0,0 +1,65 @@ +package net.sourceforge.plantuml.creole.rosetta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.cucadiagram.Display; + +public class Rosetta { + + private final List unicodeHtml; + + public static Rosetta fromUnicodeHtml(List lines) { + return new Rosetta(lines); + } + + public static Rosetta fromSyntax(WikiLanguage syntaxSource, String... wiki) { + return new Rosetta(syntaxSource, Arrays.asList(wiki)); + } + + public static Rosetta fromSyntax(WikiLanguage syntaxSource, List wiki) { + return new Rosetta(syntaxSource, wiki); + } + + public static Rosetta fromSyntax(WikiLanguage syntaxSource, Display display) { + return new Rosetta(syntaxSource, from(display)); + } + + private static List from(Display display) { + final List result = new ArrayList(); + for (CharSequence cs : display) { + result.add(cs.toString()); + } + return result; + } + + private Rosetta(List lines) { + this.unicodeHtml = new ArrayList(lines); + } + + private Rosetta(WikiLanguage syntaxSource, List wiki) { + final ReaderWiki reader; + if (syntaxSource == WikiLanguage.DOKUWIKI) { + reader = new ReaderDokuwiki(); + } else if (syntaxSource == WikiLanguage.CREOLE) { + reader = new ReaderCreole(); +// } else if (syntaxSource == WikiLanguage.MARKDOWN) { +// reader = new ReaderMarkdown(); +// } else if (syntaxSource == WikiLanguage.ASCIIDOC) { +// reader = new ReaderAsciidoc(); + } else { + throw new UnsupportedOperationException(); + } + this.unicodeHtml = reader.transform(wiki); + } + + public List translateTo(WikiLanguage syntaxDestination) { + final List html = new ArrayList(); + final WriterWiki writer = new WriterWiki(syntaxDestination); + html.addAll(writer.transform(unicodeHtml)); + return Collections.unmodifiableList(html); + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/StripeRow.java b/src/net/sourceforge/plantuml/creole/rosetta/StripeRow.java new file mode 100644 index 000000000..41f0e3ce6 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/StripeRow.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.creole.rosetta; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.creole.Stripe; +import net.sourceforge.plantuml.creole.atom.Atom; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.FontStyle; + +public class StripeRow implements Stripe { + + private final List atoms = new ArrayList(); + + public Atom getLHeader() { + return null; + } + + public List getAtoms() { + return Collections.unmodifiableList(atoms); + } + + public void add(Atom atom) { + atoms.add(atom); + } + + private static final Pattern bold = Pattern.compile("^" + WikiLanguage.UNICODE.tag("strong") + "(.*)$"); + private static final Pattern unbold = Pattern.compile("^" + WikiLanguage.UNICODE.slashTag("strong") + "(.*)$"); + private static final Pattern italic = Pattern.compile("^" + WikiLanguage.UNICODE.tag("em") + "(.*)$"); + private static final Pattern unitalic = Pattern.compile("^" + WikiLanguage.UNICODE.slashTag("em") + "(.*)$"); + private static final Pattern strike = Pattern.compile("^" + WikiLanguage.UNICODE.tag("strike") + "(.*)$"); + private static final Pattern unstrike = Pattern.compile("^" + WikiLanguage.UNICODE.slashTag("strike") + "(.*)$"); + + private static Pattern getPattern(String line) { + if (bold.matcher(line).find()) { + return bold; + } + if (unbold.matcher(line).find()) { + return unbold; + } + if (italic.matcher(line).find()) { + return italic; + } + if (unitalic.matcher(line).find()) { + return unitalic; + } + return null; + } + + public static StripeRow parseUnicode(String line, FontConfiguration fontConfiguration) { + final StripeRow result = new StripeRow(); + StringBuilder tmp = new StringBuilder(); + while (line.length() > 0) { + final Pattern cmd = getPattern(line); + if (cmd == null) { + tmp.append(line.charAt(0)); + line = line.substring(1); + continue; + } + if (tmp.length() > 0) { + result.add(AtomText22.create(tmp.toString(), fontConfiguration)); + tmp.setLength(0); + } + final Matcher matcher = cmd.matcher(line); + matcher.find(); + if (cmd == bold) { + fontConfiguration = fontConfiguration.bold(); + } else if (cmd == unbold) { + fontConfiguration = fontConfiguration.unbold(); + } else if (cmd == italic) { + fontConfiguration = fontConfiguration.italic(); + } else if (cmd == unitalic) { + fontConfiguration = fontConfiguration.unitalic(); + } else if (cmd == strike) { + fontConfiguration = fontConfiguration.add(FontStyle.STRIKE); + } else if (cmd == unstrike) { + fontConfiguration = fontConfiguration.remove(FontStyle.STRIKE); + } else { + throw new IllegalStateException(); + } + line = matcher.group(1); + } + assert line.length() == 0; + if (tmp.length() > 0) { + result.add(AtomText22.create(tmp.toString(), fontConfiguration)); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/URosetta.java b/src/net/sourceforge/plantuml/creole/rosetta/URosetta.java new file mode 100644 index 000000000..dc366d561 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/URosetta.java @@ -0,0 +1,41 @@ +/* ======================================================================== + * 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.rosetta; + +import net.sourceforge.plantuml.ugraphic.UShape; + +public interface URosetta extends UShape { +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/WikiLanguage.java b/src/net/sourceforge/plantuml/creole/rosetta/WikiLanguage.java new file mode 100644 index 000000000..28e176057 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/WikiLanguage.java @@ -0,0 +1,110 @@ +package net.sourceforge.plantuml.creole.rosetta; + +public enum WikiLanguage { + DOKUWIKI, MARKDOWN, ASCIIDOC, MEDIAWIKI, CREOLE, UNICODE, HTML_DEBUG; + + public String toString() { + return super.toString().toLowerCase(); + } + + static class MyChar { + + final String unicode; + final String htmlDebug; + + MyChar(String unicode, String htmlDebug) { + this.unicode = unicode; + this.htmlDebug = htmlDebug; + } + + String toRightSyntax(WikiLanguage lg) { + if (lg == WikiLanguage.UNICODE) { + return "" + unicode; + } else if (lg == WikiLanguage.HTML_DEBUG) { + return "" + htmlDebug; + } + throw new UnsupportedOperationException(); + } + + public String toHtmlDebug(String s) { + return s.replace(unicode, htmlDebug); + } + } + + static public String toHtmlDebug(String s) { + s = START.toHtmlDebug(s); + s = END.toHtmlDebug(s); + s = SEMICOLON.toHtmlDebug(s); + s = EQUALS.toHtmlDebug(s); + s = EOB.toHtmlDebug(s); + return s; + } + + private static final MyChar START = new MyChar("\uF800", "<<{{"); + private static final MyChar END = new MyChar("\uF802", "<>"); + + public static String hideCharsF7(String s) { + final StringBuilder sb = new StringBuilder(s.length()); + for (char ch : s.toCharArray()) { + sb.append(toF7(ch)); + } + return sb.toString(); + } + + public static String restoreAllCharsF7AndDoEscapeForBackSlash(String s) { + return restoreAllCharsF7(s); + } + + public static String restoreAllCharsF7(String s) { + final StringBuilder sb = new StringBuilder(s.length()); + for (char ch : s.toCharArray()) { + if (ch >= '\uF700' && ch <= '\uF7FF') { + ch = (char) (ch - '\uF700'); + } + sb.append(ch); + } + return sb.toString(); + } + + public static char toF7(char ch) { + if (ch < 127) { + return (char) ('\uF700' + ch); + } + return ch; + } + + public String slashTag(String tagName) { + final StringBuilder tmp = new StringBuilder(); + tmp.append(END.toRightSyntax(this)); + tmp.append(tagName); + tmp.append(SEMICOLON.toRightSyntax(this)); + tmp.append(EOB.toRightSyntax(this)); + return tmp.toString(); + } + + public String tag(String tagName) { + final StringBuilder tmp = new StringBuilder(); + tmp.append(START.toRightSyntax(this)); + tmp.append(tagName); + tmp.append(SEMICOLON.toRightSyntax(this)); + tmp.append(EOB.toRightSyntax(this)); + return tmp.toString(); + } + + public String tag(String tagName, String name, String value) { + final StringBuilder tmp = new StringBuilder(); + tmp.append(START.toRightSyntax(this)); + tmp.append(tagName); + tmp.append(SEMICOLON.toRightSyntax(this)); + tmp.append(name); + tmp.append(EQUALS.toRightSyntax(this)); + tmp.append(value); + tmp.append(SEMICOLON.toRightSyntax(this)); + tmp.append(EOB.toRightSyntax(this)); + return tmp.toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/WriterWiki.java b/src/net/sourceforge/plantuml/creole/rosetta/WriterWiki.java new file mode 100644 index 000000000..cdcb27c3c --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/rosetta/WriterWiki.java @@ -0,0 +1,28 @@ +package net.sourceforge.plantuml.creole.rosetta; + +import java.util.ArrayList; +import java.util.List; + +public class WriterWiki { + + private final WikiLanguage syntaxDestination; + + public WriterWiki(WikiLanguage syntaxDestination) { + this.syntaxDestination = syntaxDestination; + if (syntaxDestination != WikiLanguage.HTML_DEBUG && syntaxDestination != WikiLanguage.UNICODE) { + throw new IllegalArgumentException(syntaxDestination.toString()); + } + } + + public List transform(List data) { + if (syntaxDestination == WikiLanguage.UNICODE) { + return data; + } + final List result = new ArrayList(); + for (String s : data) { + result.add(WikiLanguage.toHtmlDebug(s)); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java index 032642187..2be9eb70c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -154,15 +154,17 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo } else { final String s = s2.toString(); if (manageHorizontalLine && isBlockSeparator(s)) { - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, - stereotype, entity), separator, title)); + blocks.add(decorate(stringBounder, + new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype, entity), + separator, title)); separator = s.charAt(0); title = getTitle(s, skinParam); members = new ArrayList(); - } else if (CreoleParser.isTreeStart(s)) { + } else if (Parser.isTreeStart(s)) { if (members.size() > 0) { - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, - align, stereotype, entity), separator, title)); + blocks.add(decorate(stringBounder, + new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype, entity), + separator, title)); } members = new ArrayList(); final List allTree = buildAllTree(s, it); @@ -181,8 +183,8 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo if (inEllipse && members.size() == 0) { members.add(new Member("", false, false)); } - blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype, - entity), separator, title)); + blocks.add(decorate(stringBounder, + new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype, entity), separator, title)); if (blocks.size() == 1) { this.area2 = blocks.get(0); @@ -198,7 +200,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo result.add(init); while (it.hasNext()) { final CharSequence s = it.next(); - if (CreoleParser.isTreeStart(StringUtils.trinNoTrace(s))) { + if (Parser.isTreeStart(StringUtils.trinNoTrace(s))) { result.add(s); } else { it.previous(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java index 0e235f473..4ecda3a2d 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java @@ -57,7 +57,7 @@ import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; import net.sourceforge.plantuml.creole.SheetBlock2; @@ -526,8 +526,9 @@ public class Display implements Iterable { private TextBlock getCreole(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode, FontConfiguration stereotypeConfiguration) { - final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode, - stereotypeConfiguration).createSheet(this); + final Sheet sheet = Parser + .build(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode, stereotypeConfiguration) + .createSheet(this); final double padding = spriteContainer == null ? 0 : spriteContainer.getPadding(); final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize, padding); return new SheetBlock2(sheetBlock1, sheetBlock1, new UStroke(1.5)); @@ -544,4 +545,35 @@ public class Display implements Iterable { } + public boolean hasSeveralGuideLines() { + return hasSeveralGuideLines(displayData); + } + + public static boolean hasSeveralGuideLines(String s) { + final List splitted = Arrays.asList(s.split("\\\\n")); + return hasSeveralGuideLines(splitted); + } + + private static boolean hasSeveralGuideLines(Collection all) { + if (all.size() <= 1) { + return false; + } + for (CharSequence cs : all) { + final String s = cs.toString(); + if (s.startsWith("< ")) { + return true; + } + if (s.startsWith("> ")) { + return true; + } + if (s.endsWith(" <")) { + return true; + } + if (s.endsWith(" >")) { + return true; + } + } + return false; + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java index 7861fc0e3..38e34f4f1 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Link.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -90,7 +90,7 @@ public class Link extends WithLinkType implements Hideable, Removeable { private boolean constraint = true; private boolean inverted = false; - private LinkArrow linkArrow = LinkArrow.NONE; + private LinkArrow linkArrow = LinkArrow.NONE_OR_SEVERAL; private boolean opale; private boolean horizontalSolitary; diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkArrow.java b/src/net/sourceforge/plantuml/cucadiagram/LinkArrow.java index 731094b5f..cccf70219 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LinkArrow.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkArrow.java @@ -35,9 +35,12 @@ */ package net.sourceforge.plantuml.cucadiagram; +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.svek.GuideLine; + public enum LinkArrow { - NONE, DIRECT_NORMAL, BACKWARD; + NONE_OR_SEVERAL, DIRECT_NORMAL, BACKWARD; public LinkArrow reverse() { if (this == DIRECT_NORMAL) { @@ -46,7 +49,22 @@ public enum LinkArrow { if (this == BACKWARD) { return DIRECT_NORMAL; } - return NONE; + return NONE_OR_SEVERAL; + } + + public GuideLine mute(final GuideLine guide) { + switch (this) { + case DIRECT_NORMAL: + return guide; + case BACKWARD: + return new GuideLine() { + public Direction getArrowDirection() { + return guide.getArrowDirection().getInv(); + } + }; + + } + throw new UnsupportedOperationException(); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java index 565a71200..2163e633a 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java @@ -200,7 +200,7 @@ public class MethodsOrFieldsArea extends AbstractTextBlock implements TextBlockW } bloc.drawU(ug); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index 8fe30c666..856ac185a 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -53,7 +53,7 @@ import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexResult; -import net.sourceforge.plantuml.creole.command.CommandCreoleImg; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.sprite.Sprite; import net.sourceforge.plantuml.sprite.SpriteUtils; @@ -122,7 +122,7 @@ public class Stereotype implements CharSequence { if (label.startsWith("<<$") && label.endsWith(">>")) { final RegexResult mCircleSprite = circleSprite.matcher(label); this.spriteName = mCircleSprite.get("NAME", 0); - this.spriteScale = CommandCreoleImg.getScale(mCircleSprite.get("SCALE", 0), 1); + this.spriteScale = Parser.getScale(mCircleSprite.get("SCALE", 0), 1); } else { this.spriteName = null; } @@ -157,7 +157,7 @@ public class Stereotype implements CharSequence { this.htmlColor = col == null ? HColorUtils.BLACK : col; this.spriteName = mCircleSprite.get("NAME", 0); this.character = '\0'; - this.spriteScale = CommandCreoleImg.getScale(mCircleSprite.get("SCALE", 0), 1); + this.spriteScale = Parser.getScale(mCircleSprite.get("SCALE", 0), 1); } else if (mCircleChar != null) { if (StringUtils.isNotEmpty(mCircleChar.get("LABEL", 0))) { local = "<<" + mCircleChar.get("LABEL", 0) + ">>"; diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java index 1c3bfd65b..1950108ac 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageDesignedDomain.java @@ -145,7 +145,7 @@ public class EntityImageDesignedDomain extends AbstractEntityImage { header.drawU(ug.apply(UTranslate.dx(4)), dimTotal.getWidth(), dimTitle.getHeight()); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java index 5882ff700..a1326091e 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageDomain.java @@ -149,7 +149,7 @@ public class EntityImageDomain extends AbstractEntityImage { footer.drawU(ug.apply(new UTranslate(dimTotal.getWidth() - dimTag.getWidth(), dimTitle.getHeight())), dimTag.getWidth(), dimTag.getHeight()); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java index 4df97fd46..96308e5aa 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageMachine.java @@ -144,7 +144,7 @@ public class EntityImageMachine extends AbstractEntityImage { header.drawU(ug.apply(UTranslate.dx(5)), dimTotal.getWidth(), dimTitle.getHeight()); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java b/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java index 4f3ba285b..6bd46d42b 100644 --- a/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java +++ b/src/net/sourceforge/plantuml/descdiagram/EntityImageRequirement.java @@ -132,7 +132,7 @@ public class EntityImageRequirement extends AbstractEntityImage { ellipse.drawU(ug2); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java index 3b950fbd1..da955f567 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java @@ -42,9 +42,6 @@ import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.IRegex; -import net.sourceforge.plantuml.command.regex.Matcher2; -import net.sourceforge.plantuml.command.regex.MyPattern; -import net.sourceforge.plantuml.command.regex.Pattern2; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexOptional; @@ -56,7 +53,6 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.LinkArrow; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.cucadiagram.Stereotype; @@ -82,7 +78,7 @@ public class CommandLinkElement extends SingleLineCommand2 { return RegexConcat.build(CommandLinkElement.class.getName(), RegexLeaf.start(), // getGroup("ENT1"), // RegexLeaf.spaceZeroOrMore(), // - new RegexOptional(new RegexLeaf("LABEL1", "[%g]([^%g]+)[%g]")), // + new RegexOptional(new RegexLeaf("FIRST_LABEL", "[%g]([^%g]+)[%g]")), // RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("HEAD2", "(0\\)|<<|[<^*+#0@)]|<\\|[\\|\\:]?|[%s]+o)?"), // new RegexLeaf("BODY1", "([-=.~]+)"), // @@ -93,7 +89,7 @@ public class CommandLinkElement extends SingleLineCommand2 { new RegexLeaf("BODY2", "([-=.~]*)"), // new RegexLeaf("HEAD1", "(\\(0|>>|[>^*+#0@(]|[\\:\\|]?\\|>|\\\\\\\\|o[%s]+)?"), // RegexLeaf.spaceZeroOrMore(), // - new RegexOptional(new RegexLeaf("LABEL2", "[%g]([^%g]+)[%g]")), // + new RegexOptional(new RegexLeaf("SECOND_LABEL", "[%g]([^%g]+)[%g]")), // RegexLeaf.spaceZeroOrMore(), // getGroup("ENT2"), // RegexLeaf.spaceZeroOrMore(), // @@ -223,78 +219,6 @@ public class CommandLinkElement extends SingleLineCommand2 { "([\\p{L}0-9_.]+|\\(\\)[%s]*[\\p{L}0-9_.]+|\\(\\)[%s]*[%g][^%g]+[%g]|:[^:]+:|(?!\\[\\*\\])\\[[^\\[\\]]+\\]|\\((?!\\*\\))[^)]+\\))"); } - static class Labels { - private String firstLabel; - private String secondLabel; - private String labelLink; - private LinkArrow linkArrow = LinkArrow.NONE; - - Labels(RegexResult arg) { - firstLabel = arg.get("LABEL1", 0); - secondLabel = arg.get("LABEL2", 0); - labelLink = arg.get("LABEL_LINK", 0); - - if (labelLink != null) { - if (firstLabel == null && secondLabel == null) { - init(); - } - labelLink = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(labelLink, "\""); - - if ("<".equals(labelLink)) { - linkArrow = LinkArrow.BACKWARD; - labelLink = null; - } else if (">".equals(labelLink)) { - linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = null; - } else if (labelLink != null && labelLink.startsWith("< ")) { - linkArrow = LinkArrow.BACKWARD; - labelLink = StringUtils.trin(labelLink.substring(2)); - } else if (labelLink != null && labelLink.startsWith("> ")) { - linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = StringUtils.trin(labelLink.substring(2)); - } else if (labelLink != null && labelLink.endsWith(" >")) { - linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = StringUtils.trin(labelLink.substring(0, labelLink.length() - 2)); - } else if (labelLink != null && labelLink.endsWith(" <")) { - linkArrow = LinkArrow.BACKWARD; - labelLink = StringUtils.trin(labelLink.substring(0, labelLink.length() - 2)); - } - - } - - } - - private void init() { - final Pattern2 p1 = MyPattern.cmpile("^[%g]([^%g]+)[%g]([^%g]+)[%g]([^%g]+)[%g]$"); - final Matcher2 m1 = p1.matcher(labelLink); - if (m1.matches()) { - firstLabel = m1.group(1); - labelLink = StringUtils - .trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m1.group(2)))); - secondLabel = m1.group(3); - return; - } - final Pattern2 p2 = MyPattern.cmpile("^[%g]([^%g]+)[%g]([^%g]+)$"); - final Matcher2 m2 = p2.matcher(labelLink); - if (m2.matches()) { - firstLabel = m2.group(1); - labelLink = StringUtils - .trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m2.group(2)))); - secondLabel = null; - return; - } - final Pattern2 p3 = MyPattern.cmpile("^([^%g]+)[%g]([^%g]+)[%g]$"); - final Matcher2 m3 = p3.matcher(labelLink); - if (m3.matches()) { - firstLabel = null; - labelLink = StringUtils - .trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m3.group(1)))); - secondLabel = m3.group(2); - } - } - - } - @Override protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLocation location, RegexResult arg) { final String ent1String = arg.get("ENT1", 0); @@ -327,10 +251,10 @@ public class CommandLinkElement extends SingleLineCommand2 { cl1 = getFoo1(diagram, code1, ident1, ident1pure); cl2 = getFoo1(diagram, code2, ident2, ident2pure); } - Link link = new Link(cl1, cl2, linkType, Display.getWithNewlines(labels.labelLink), queue.length(), - labels.firstLabel, labels.secondLabel, diagram.getLabeldistance(), diagram.getLabelangle(), + Link link = new Link(cl1, cl2, linkType, Display.getWithNewlines(labels.getLabelLink()), queue.length(), + labels.getFirstLabel(), labels.getSecondLabel(), diagram.getLabeldistance(), diagram.getLabelangle(), diagram.getSkinParam().getCurrentStyleBuilder()); - link.setLinkArrow(labels.linkArrow); + link.setLinkArrow(labels.getLinkArrow()); if (dir == Direction.LEFT || dir == Direction.UP) { link = link.getInv(); } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/Labels.java b/src/net/sourceforge/plantuml/descdiagram/command/Labels.java new file mode 100644 index 000000000..008c9f812 --- /dev/null +++ b/src/net/sourceforge/plantuml/descdiagram/command/Labels.java @@ -0,0 +1,115 @@ +/* ======================================================================== + * 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 + * Contribution : Hisashi Miyashita + * + */ +package net.sourceforge.plantuml.descdiagram.command; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.regex.Matcher2; +import net.sourceforge.plantuml.command.regex.MyPattern; +import net.sourceforge.plantuml.command.regex.Pattern2; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.LinkArrow; + +public class Labels { + + private String firstLabel; + private String secondLabel; + private final StringWithArrow stringWithArrow; + + public Labels(RegexResult arg) { + this.firstLabel = arg.get("FIRST_LABEL", 0); + this.secondLabel = arg.get("SECOND_LABEL", 0); + String labelLink = arg.get("LABEL_LINK", 0); + + if (labelLink != null) { + labelLink = init(labelLink); + } + + this.stringWithArrow = new StringWithArrow(labelLink); + + } + + private String init(String labelLink) { + if (firstLabel == null && secondLabel == null) { + final Pattern2 p1 = MyPattern.cmpile("^[%g]([^%g]+)[%g]([^%g]+)[%g]([^%g]+)[%g]$"); + final Matcher2 m1 = p1.matcher(labelLink); + if (m1.matches()) { + firstLabel = m1.group(1); + secondLabel = m1.group(3); + return StringUtils + .trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m1.group(2)))); + } + final Pattern2 p2 = MyPattern.cmpile("^[%g]([^%g]+)[%g]([^%g]+)$"); + final Matcher2 m2 = p2.matcher(labelLink); + if (m2.matches()) { + firstLabel = m2.group(1); + secondLabel = null; + return StringUtils + .trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m2.group(2)))); + } + final Pattern2 p3 = MyPattern.cmpile("^([^%g]+)[%g]([^%g]+)[%g]$"); + final Matcher2 m3 = p3.matcher(labelLink); + if (m3.matches()) { + firstLabel = null; + secondLabel = m3.group(2); + return StringUtils + .trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m3.group(1)))); + } + } + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(labelLink, "\""); + } + + public final String getFirstLabel() { + return firstLabel; + } + + public final String getSecondLabel() { + return secondLabel; + } + + public final String getLabelLink() { + return stringWithArrow.getLabel(); + } + + public final LinkArrow getLinkArrow() { + return stringWithArrow.getLinkArrow(); + } + + public Display getDisplay() { + return stringWithArrow.getDisplay(); + } + +} diff --git a/src/net/sourceforge/plantuml/descdiagram/command/StringWithArrow.java b/src/net/sourceforge/plantuml/descdiagram/command/StringWithArrow.java new file mode 100644 index 000000000..1d72b7459 --- /dev/null +++ b/src/net/sourceforge/plantuml/descdiagram/command/StringWithArrow.java @@ -0,0 +1,144 @@ +/* ======================================================================== + * 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 + * Contribution : Hisashi Miyashita + * + */ +package net.sourceforge.plantuml.descdiagram.command; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.LinkArrow; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockArrow; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.VerticalAlignment; +import net.sourceforge.plantuml.svek.DirectionalTextBlock; +import net.sourceforge.plantuml.svek.GuideLine; + +public class StringWithArrow { + + private final String label; + private final LinkArrow linkArrow; + + public StringWithArrow(String completeLabel) { + if (completeLabel == null) { + this.linkArrow = LinkArrow.NONE_OR_SEVERAL; + this.label = null; + return; + } + completeLabel = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(completeLabel, "\""); + if (Display.hasSeveralGuideLines(completeLabel)) { + this.linkArrow = LinkArrow.NONE_OR_SEVERAL; + this.label = completeLabel; + } else { + + if ("<".equals(completeLabel)) { + this.linkArrow = LinkArrow.BACKWARD; + this.label = null; + } else if (">".equals(completeLabel)) { + this.linkArrow = LinkArrow.DIRECT_NORMAL; + this.label = null; + } else if (completeLabel.startsWith("< ")) { + this.linkArrow = LinkArrow.BACKWARD; + this.label = StringUtils.trin(completeLabel.substring(2)); + } else if (completeLabel.startsWith("> ")) { + this.linkArrow = LinkArrow.DIRECT_NORMAL; + this.label = StringUtils.trin(completeLabel.substring(2)); + } else if (completeLabel.endsWith(" >")) { + this.linkArrow = LinkArrow.DIRECT_NORMAL; + this.label = StringUtils.trin(completeLabel.substring(0, completeLabel.length() - 2)); + } else if (completeLabel.endsWith(" <")) { + this.linkArrow = LinkArrow.BACKWARD; + this.label = StringUtils.trin(completeLabel.substring(0, completeLabel.length() - 2)); + } else { + this.linkArrow = LinkArrow.NONE_OR_SEVERAL; + this.label = completeLabel; + } + } + } + + public final String getLabel() { + return label; + } + + public final LinkArrow getLinkArrow() { + return linkArrow; + } + + public final Display getDisplay() { + return Display.getWithNewlines(label); + } + + static public TextBlock addMagicArrow(TextBlock label, GuideLine guide, FontConfiguration font) { + final TextBlock arrowRight = new TextBlockArrow(Direction.RIGHT, font); + final TextBlock arrowLeft = new TextBlockArrow(Direction.LEFT, font); + final TextBlock arrowUp = new TextBlockArrow(Direction.UP, font); + final TextBlock arrowDown = new TextBlockArrow(Direction.DOWN, font); + final TextBlock right = TextBlockUtils.mergeLR(label, arrowRight, VerticalAlignment.CENTER); + final TextBlock left = TextBlockUtils.mergeLR(arrowLeft, label, VerticalAlignment.CENTER); + final TextBlock up = TextBlockUtils.mergeTB(arrowUp, label, HorizontalAlignment.CENTER); + final TextBlock down = TextBlockUtils.mergeTB(label, arrowDown, HorizontalAlignment.CENTER); + return new DirectionalTextBlock(guide, right, left, up, down); + } + + static private TextBlock addMagicArrow2(TextBlock label, GuideLine guide, FontConfiguration font) { + final TextBlock arrowRight = new TextBlockArrow(Direction.RIGHT, font); + final TextBlock arrowLeft = new TextBlockArrow(Direction.LEFT, font); + final TextBlock arrowUp = new TextBlockArrow(Direction.UP, font); + final TextBlock arrowDown = new TextBlockArrow(Direction.DOWN, font); + final TextBlock right = TextBlockUtils.mergeLR(label, arrowRight, VerticalAlignment.CENTER); + final TextBlock left = TextBlockUtils.mergeLR(arrowLeft, label, VerticalAlignment.CENTER); + final TextBlock up = TextBlockUtils.mergeLR(arrowUp, label, VerticalAlignment.CENTER); + final TextBlock down = TextBlockUtils.mergeLR(label, arrowDown, VerticalAlignment.CENTER); + return new DirectionalTextBlock(guide, right, left, up, down); + } + + public static TextBlock addSeveralMagicArrows(Display label, GuideLine guide, FontConfiguration font, + HorizontalAlignment alignment, ISkinParam skinParam) { + TextBlock result = TextBlockUtils.EMPTY_TEXT_BLOCK; + for (CharSequence cs : label) { + StringWithArrow tmp = new StringWithArrow(cs.toString()); + TextBlock block = tmp.getDisplay().create9(font, alignment, skinParam, skinParam.maxMessageSize()); + if (tmp.getLinkArrow() != LinkArrow.NONE_OR_SEVERAL) { + block = StringWithArrow.addMagicArrow2(block, tmp.getLinkArrow().mute(guide), font); + } + result = TextBlockUtils.mergeTB(result, block, alignment); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/ditaa/PSystemDitaa.java b/src/net/sourceforge/plantuml/ditaa/PSystemDitaa.java index 9f1317801..cc5a32c95 100644 --- a/src/net/sourceforge/plantuml/ditaa/PSystemDitaa.java +++ b/src/net/sourceforge/plantuml/ditaa/PSystemDitaa.java @@ -39,6 +39,8 @@ import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import javax.imageio.ImageIO; @@ -46,9 +48,11 @@ import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.svek.GraphvizCrash; public class PSystemDitaa extends AbstractPSystem { @@ -120,16 +124,18 @@ public class PSystemDitaa extends AbstractPSystem { // final Diagram diagram = new Diagram(grid, options, processingOptions); final Class 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); + 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 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); @@ -138,10 +144,15 @@ public class PSystemDitaa extends AbstractPSystem { final int width = image.getWidth(); final int height = image.getHeight(); return new ImageDataSimple(width, height); - } catch (Exception e) { - e.printStackTrace(); + } catch (Throwable e) { + final List strings = new ArrayList(); + strings.add("DITAA has crashed"); + strings.add(" "); + GraphvizCrash.youShouldSendThisDiagram(strings); + strings.add(" "); + UmlDiagram.exportDiagramError(os, e, new FileFormatOption(FileFormat.PNG), seed(), null, null, strings); + return ImageDataSimple.error(); } - return null; } diff --git a/src/net/sourceforge/plantuml/eps/EpsGraphics.java b/src/net/sourceforge/plantuml/eps/EpsGraphics.java index f20e81c67..9be0f6943 100644 --- a/src/net/sourceforge/plantuml/eps/EpsGraphics.java +++ b/src/net/sourceforge/plantuml/eps/EpsGraphics.java @@ -97,8 +97,8 @@ public class EpsGraphics { true)); roundrect.add(new PostScriptCommandRaw( "2 index 5 index add 1 index sub 2 index 5 index add 2 index sub 2 index 0 90 arc", true)); - roundrect.add(new PostScriptCommandRaw("dup 3 index add 2 index 5 index add 2 index sub 2 index 90 180 arc", - true)); + roundrect.add( + new PostScriptCommandRaw("dup 3 index add 2 index 5 index add 2 index sub 2 index 90 180 arc", true)); roundrect.add(new PostScriptCommandRaw("pop pop pop pop pop ", true)); } @@ -401,8 +401,8 @@ public class EpsGraphics { } } - public void epsRectangle(double x, double y, double width, double height, double rx, double ry, - HColorGradient gr, ColorMapper mapper) { + public void epsRectangle(double x, double y, double width, double height, double rx, double ry, HColorGradient gr, + ColorMapper mapper) { checkCloseDone(); ensureVisible(x, y); ensureVisible(x + width, y + height); @@ -482,19 +482,20 @@ public class EpsGraphics { append("[" + dashSpace + " " + dashVisible + "] 0 setdash", true); } // if (isDashed3() || fill) { - append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " simplerect", true); - simplerectUsed = true; + append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " simplerect", true); + simplerectUsed = true; // } } /** - * Converts a counter clockwise angle to a clockwise - * angle. i.e. 0 -> 360, 90 -> 270, 180 -> 180, 270 -> 90 + * Converts a counter clockwise angle to a clockwise angle. i.e. 0 -> 360, 90 -> + * 270, 180 -> 180, 270 -> 90 + * * @param counterClockwise counter clockwise angle in degrees * @return clockwise angle in degrees */ - private double convertToClockwiseAngle(double counterClockwise) { - return 360.0 - counterClockwise; + private int convertToClockwiseAngle(double counterClockwise) { + return (int) (360.0 - counterClockwise); } public void epsEllipse(double x, double y, double xRadius, double yRadius, double start, double extend) { @@ -509,7 +510,8 @@ public class EpsGraphics { // if (fillcolor != null) { // appendColor(fillcolor); // append("newpath", true); - // append(format(x) + " " + format(y / scale) + " " + format(xRadius) + " 0 360 arc", true); + // append(format(x) + " " + format(y / scale) + " " + format(xRadius) + " 0 360 + // arc", true); // append("closepath eofill", true); // } @@ -518,12 +520,9 @@ public class EpsGraphics { appendColor(color); append("newpath", true); - - final double a1 = convertToClockwiseAngle(start + extend); final double a2 = convertToClockwiseAngle(start); - append(format(x) + " " + format(y / scale) + " " + format(xRadius) + " " + (long)a1 + " " + (long)a2 - + " arc", true); + append(format(x) + " " + format(y / scale) + " " + format(xRadius) + " " + a1 + " " + a2 + " arc", true); append("stroke", true); } @@ -630,8 +629,8 @@ public class EpsGraphics { } final public void curvetoNoMacro(double x1, double y1, double x2, double y2, double x3, double y3) { - append(format(x1) + " " + format(y1) + " " + format(x2) + " " + format(y2) + " " + format(x3) + " " - + format(y3) + " curveto", true); + append(format(x1) + " " + format(y1) + " " + format(x2) + " " + format(y2) + " " + format(x3) + " " + format(y3) + + " curveto", true); ensureVisible(x1, y1); ensureVisible(x2, y2); ensureVisible(x3, y3); @@ -649,16 +648,16 @@ public class EpsGraphics { } public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) { - append(format(x1) + " " + format(y1) + " " + format(x2) + " " + format(y2) + " " + format(x3) + " " - + format(y3) + " curveto", true); + append(format(x1) + " " + format(y1) + " " + format(x2) + " " + format(y2) + " " + format(x3) + " " + format(y3) + + " curveto", true); ensureVisible(x1, y1); ensureVisible(x2, y2); ensureVisible(x3, y3); } public void quadto(double x1, double y1, double x2, double y2) { - append(format(x1) + " " + format(y1) + " " + format(x1) + " " + format(y1) + " " + format(x2) + " " - + format(y2) + " curveto", true); + append(format(x1) + " " + format(y1) + " " + format(x1) + " " + format(y1) + " " + format(x2) + " " + format(y2) + + " curveto", true); ensureVisible(x1, y1); ensureVisible(x2, y2); } diff --git a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java index e5e5cc84a..43d9b6a7e 100644 --- a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java +++ b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java @@ -210,7 +210,7 @@ public class FontConfiguration { FontPosition.NORMAL, new SvgAttributes(), hyperlink, hyperlinkColor, useUnderlineForHyperlink, tabSize); } - FontConfiguration add(FontStyle style) { + public FontConfiguration add(FontStyle style) { final EnumSet r = styles.clone(); if (style == FontStyle.PLAIN) { r.clear(); @@ -228,6 +228,14 @@ public class FontConfiguration { return add(FontStyle.BOLD); } + public FontConfiguration unbold() { + return remove(FontStyle.BOLD); + } + + public FontConfiguration unitalic() { + return remove(FontStyle.ITALIC); + } + public FontConfiguration underline() { return add(FontStyle.UNDERLINE); } @@ -243,7 +251,7 @@ public class FontConfiguration { return withHyperlink(); } - FontConfiguration remove(FontStyle style) { + public FontConfiguration remove(FontStyle style) { final EnumSet r = styles.clone(); r.remove(style); return new FontConfiguration(r, motherFont, motherColor, currentFont, currentColor, extendedColor, fontPosition, diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index 164010cbc..cb541c2cb 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -268,7 +268,10 @@ public class QuoteUtils { "...naq gnk phgf. Gung'yy fubj gurz znegvnaf.", "Jurarire V srry gur arrq gb rkrepvfr, V yvr qbja hagvy vg tbrf njnl", "Ernyvgl pbagvahrf gb ehva zl yvsr", "Vs lbh gvpxyr hf, qb jr abg ynhtu?", "V xabj n HQC wbxr, ohg lbh zvtug abg trg vg", - "Chvfdhr prf zlfgrerf abhf qrcnffrag, srvtabaf q'ra rger y'betnavfngrhe."); + "Chvfdhr prf zlfgrerf abhf qrcnffrag, srvtabaf q'ra rger y'betnavfngrhe.", + "V qba'g gnxr nal erfcbafvovyvgl ng nyy", + "Gurer'f n jbeq sbe crbcyr jub guvax rirelbar vf pbafcvevat ntnvafg gurz: creprcgvir", + "V'yy yrg gung cnff orpnhfr guvf vf tbbqolr"); private QuoteUtils() { } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java index 94e4a959d..f879dc024 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java @@ -68,6 +68,8 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils; public class TextBlockUtils { + public static final TextBlock EMPTY_TEXT_BLOCK = TextBlockUtils.empty(0, 0); + public static TextBlock bordered(TextBlock textBlock, UStroke stroke, HColor borderColor, HColor backgroundColor, double cornersize) { return new TextBlockBordered(textBlock, stroke, borderColor, backgroundColor, cornersize); @@ -143,10 +145,22 @@ public class TextBlockUtils { } public static TextBlock mergeLR(TextBlock b1, TextBlock b2, VerticalAlignment verticallAlignment) { + if (b1 == EMPTY_TEXT_BLOCK) { + return b2; + } + if (b2 == EMPTY_TEXT_BLOCK) { + return b1; + } return new TextBlockHorizontal(b1, b2, verticallAlignment); } public static TextBlock mergeTB(TextBlock b1, TextBlock b2, HorizontalAlignment horizontalAlignment) { + if (b1 == EMPTY_TEXT_BLOCK) { + return b2; + } + if (b2 == EMPTY_TEXT_BLOCK) { + return b1; + } return new TextBlockVertical2(b1, b2, horizontalAlignment); } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java b/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java index 5235eda16..a0203e762 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockWithUrl.java @@ -63,7 +63,7 @@ public class TextBlockWithUrl implements TextBlock { public void drawU(UGraphic ug) { ug.startUrl(url); block.drawU(ug); - ug.closeAction(); + ug.closeUrl(); } public Dimension2D calculateDimension(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/graphic/TileText.java b/src/net/sourceforge/plantuml/graphic/TileText.java index 084cda60e..b2e9152bb 100644 --- a/src/net/sourceforge/plantuml/graphic/TileText.java +++ b/src/net/sourceforge/plantuml/graphic/TileText.java @@ -110,7 +110,7 @@ public class TileText extends AbstractTextBlock implements TextBlock { } } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/graphic/UGraphicDelegator.java b/src/net/sourceforge/plantuml/graphic/UGraphicDelegator.java index 09886f0fb..ed483d53d 100644 --- a/src/net/sourceforge/plantuml/graphic/UGraphicDelegator.java +++ b/src/net/sourceforge/plantuml/graphic/UGraphicDelegator.java @@ -44,13 +44,12 @@ import net.sourceforge.plantuml.ugraphic.color.ColorMapper; public abstract class UGraphicDelegator implements UGraphic { final private UGraphic ug; - + @Override public String toString() { return super.toString() + " " + getUg().toString(); } - public final boolean matchesProperty(String propertyName) { return ug.matchesProperty(propertyName); } @@ -79,14 +78,22 @@ public abstract class UGraphicDelegator implements UGraphic { ug.startUrl(url); } - public void closeAction() { - ug.closeAction(); + public void closeUrl() { + ug.closeUrl(); + } + + public void startGroup(String groupId) { + ug.startGroup(groupId); + } + + public void closeGroup() { + ug.closeGroup(); } protected UGraphic getUg() { return ug; } - + public void flushUg() { ug.flushUg(); } diff --git a/src/net/sourceforge/plantuml/help/Help.java b/src/net/sourceforge/plantuml/help/Help.java index 1a3d3e5e9..12d988d69 100644 --- a/src/net/sourceforge/plantuml/help/Help.java +++ b/src/net/sourceforge/plantuml/help/Help.java @@ -46,9 +46,10 @@ import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; +import net.sourceforge.plantuml.creole.legacy.CreoleParser; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -75,12 +76,11 @@ public class Help extends UmlDiagram { final Display display = Display.create(lines); final UFont font = UFont.serif(16); final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(font); - final Sheet sheet = new CreoleParser(fontConfiguration, HorizontalAlignment.LEFT, getSkinParam(), - CreoleMode.FULL).createSheet(display); + final Sheet sheet = Parser.build(fontConfiguration, HorizontalAlignment.LEFT, getSkinParam(), CreoleMode.FULL) + .createSheet(display); final SheetBlock1 sheetBlock = new SheetBlock1(sheet, LineBreakStrategy.NONE, 0); - final ImageBuilder builder = ImageBuilder.buildA(new ColorMapperIdentity(), false, null, null, null, 1.0, - null); + final ImageBuilder builder = ImageBuilder.buildA(new ColorMapperIdentity(), false, null, null, null, 1.0, null); builder.setUDrawable(sheetBlock); return builder.writeImageTOBEMOVED(fileFormat, 0, os); } diff --git a/src/net/sourceforge/plantuml/jungle/GTileNode.java b/src/net/sourceforge/plantuml/jungle/GTileNode.java index c7278456a..4ff1a328b 100644 --- a/src/net/sourceforge/plantuml/jungle/GTileNode.java +++ b/src/net/sourceforge/plantuml/jungle/GTileNode.java @@ -42,9 +42,10 @@ import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; +import net.sourceforge.plantuml.creole.legacy.CreoleParser; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -69,7 +70,8 @@ public class GTileNode extends AbstractTextBlock implements GTile { final SheetBlock1 sheetBlock1 = getTextBlock(display); final SymbolContext symbolContext = new SymbolContext(HColorUtils.MY_YELLOW, HColorUtils.BLACK); - tb = USymbol.RECTANGLE.asSmall(null, sheetBlock1, TextBlockUtils.empty(0, 0), symbolContext, HorizontalAlignment.CENTER); + tb = USymbol.RECTANGLE.asSmall(null, sheetBlock1, TextBlockUtils.empty(0, 0), symbolContext, + HorizontalAlignment.CENTER); } public static SheetBlock1 getTextBlock(final Display display) { @@ -80,7 +82,7 @@ public class GTileNode extends AbstractTextBlock implements GTile { final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.NOTE, null); - final Sheet sheet9 = new CreoleParser(fc, HorizontalAlignment.LEFT, skinParam, CreoleMode.FULL) + final Sheet sheet9 = Parser.build(fc, HorizontalAlignment.LEFT, skinParam, CreoleMode.FULL) .createSheet(display); final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet9, LineBreakStrategy.NONE, 0); return sheetBlock1; diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java index 0662c0e8f..052202723 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java @@ -128,7 +128,7 @@ public class PreprocessorUtils { return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation()); } catch (IOException e) { e.printStackTrace(); - throw EaterException.located("Cannot open URL " + e.getMessage(), s); + throw EaterException.located("Cannot open URL " + e.getMessage()); } } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java b/src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java index d8c1e65c4..f8f2dee89 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java @@ -39,19 +39,32 @@ import java.io.IOException; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.preproc.ReadLine; +import net.sourceforge.plantuml.utils.StartUtils; public class ReadFilterMergeLines implements ReadFilter { public ReadLine applyFilter(final ReadLine source) { return new ReadLine() { + + private boolean manageEndingBackslash = true; + public void close() throws IOException { source.close(); } public StringLocated readLine() throws IOException { StringLocated result = source.readLine(); - while (result != null && StringUtils.endsWithBackslash(result.getString())) { + if (result != null && StartUtils.isArobaseStartDiagram(result.getString()) + && isDitaa(result.getString())) { + this.manageEndingBackslash = false; + } + if (result != null && StartUtils.isArobaseEndDiagram(result.getString())) { + this.manageEndingBackslash = true; + } + + while (result != null && manageEndingBackslash && StringUtils.endsWithBackslash(result.getString())) { final StringLocated next = source.readLine(); if (next == null) { break; @@ -61,6 +74,10 @@ public class ReadFilterMergeLines implements ReadFilter { } return result; } + + private boolean isDitaa(String string) { + return DiagramType.getTypeFromArobaseStart(StringUtils.trinNoTrace((string))) == DiagramType.DITAA; + } }; } diff --git a/src/net/sourceforge/plantuml/project/GanttDiagram.java b/src/net/sourceforge/plantuml/project/GanttDiagram.java index d24ec7cb8..42fd0f99c 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagram.java @@ -173,8 +173,8 @@ public class GanttDiagram extends TitledDiagram implements Subject { margin2 = 0; } final double dpiFactor = scale == null ? 1 : scale.getScale(100, 100); - final ImageBuilder imageBuilder = ImageBuilder.buildB(new ColorMapperIdentity(), false, ClockwiseTopRightBottomLeft.margin1margin2((double) margin1, (double) margin2), - null, "", "", dpiFactor, null); + final ImageBuilder imageBuilder = ImageBuilder.buildB(new ColorMapperIdentity(), false, + ClockwiseTopRightBottomLeft.margin1margin2(margin1, margin2), null, getMetadata(), "", dpiFactor, null); final SkinParam skinParam = SkinParam.create(UmlDiagramType.TIMING); TextBlock result = getTextBlock(); @@ -228,8 +228,7 @@ public class GanttDiagram extends TitledDiagram implements Subject { drawConstraints(ug, timeHeader.getTimeScale()); drawTasksRect(ug); drawTasksTitle(ug); - if (printStart == null) - drawResources(ug); + drawResources(ug); } public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java index 1368bd1c0..bf515e3bc 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java @@ -141,7 +141,7 @@ public class TaskDrawRegular extends AbstractTaskDraw { ug.apply(new HColorNone().bg()).draw(full); } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/salt/Dictionary.java b/src/net/sourceforge/plantuml/salt/Dictionary.java index dc9abde05..d07f47806 100644 --- a/src/net/sourceforge/plantuml/salt/Dictionary.java +++ b/src/net/sourceforge/plantuml/salt/Dictionary.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.SpriteContainer; -import net.sourceforge.plantuml.creole.command.CommandCreoleMonospaced; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.salt.element.Element; import net.sourceforge.plantuml.salt.element.WrappedElement; import net.sourceforge.plantuml.sprite.Sprite; @@ -83,7 +83,7 @@ public class Dictionary implements SpriteContainer, ISkinSimple { } public String getMonospacedFamily() { - return CommandCreoleMonospaced.MONOSPACED; + return Parser.MONOSPACED; } public int getTabSize() { diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java index a245fc37d..c66107240 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java @@ -116,7 +116,7 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite { if (getScale() != null) { scale = getScale().getScale(size.getWidth(), size.getHeight()); } - + final int margin1; final int margin2; if (SkinParam.USE_STYLES()) { @@ -127,8 +127,9 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite { margin2 = 5; } - final ImageBuilder builder = ImageBuilder.buildB(new ColorMapperIdentity(), false, ClockwiseTopRightBottomLeft.margin1margin2((double) margin1, (double) margin2), - null, null, null, scale, HColorUtils.WHITE); + final ImageBuilder builder = ImageBuilder.buildB(new ColorMapperIdentity(), false, + ClockwiseTopRightBottomLeft.margin1margin2(margin1, margin2), null, getMetadata(), null, scale, + HColorUtils.WHITE); builder.setUDrawable(new UDrawable() { public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java index 274de3b41..694db8a97 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java @@ -86,7 +86,7 @@ abstract class Arrow extends GraphicalElement implements InGroupable { protected final void endUrl(UGraphic ug) { if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java index 36b2ed41b..de5f80161 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java @@ -345,7 +345,7 @@ public class DrawableSet { } box.getParticipantBox().drawHeadTailU(ug, topStartingY, showHead, positionTail); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalReference.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalReference.java index f686b16d6..59b4db205 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalReference.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalReference.java @@ -84,7 +84,7 @@ class GraphicalReference extends GraphicalElement implements InGroupable { } comp.drawU(ug, new Area(dim), context); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java index 93c44ba20..3daf33449 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java @@ -114,7 +114,7 @@ final class NoteBox extends GraphicalElement implements InGroupable { } comp.drawU(ug, new Area(dimensionToUse), context); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java index 123efdb88..67f54c0d2 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxFinder.java @@ -37,9 +37,10 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UBackground; +import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicNo; import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UParamNull; import net.sourceforge.plantuml.ugraphic.UShape; @@ -49,7 +50,7 @@ import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.color.HColor; -public class LiveBoxFinder implements UGraphic { +public class LiveBoxFinder extends UGraphicNo implements UGraphic { public boolean matchesProperty(String propertyName) { return false; @@ -121,12 +122,6 @@ public class LiveBoxFinder implements UGraphic { return new ColorMapperIdentity(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public void flushUg() { } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java index d3f7d1226..11697d432 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java @@ -189,7 +189,7 @@ public class LivingSpace { } comp.drawU(ug, area, context); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/Cluster.java b/src/net/sourceforge/plantuml/svek/Cluster.java index 3730c5579..bf93cd79c 100644 --- a/src/net/sourceforge/plantuml/svek/Cluster.java +++ b/src/net/sourceforge/plantuml/svek/Cluster.java @@ -399,7 +399,7 @@ public class Cluster implements Moveable { } finally { if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/DirectionalTextBlock.java b/src/net/sourceforge/plantuml/svek/DirectionalTextBlock.java new file mode 100644 index 000000000..c6093d7f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/DirectionalTextBlock.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.svek; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class DirectionalTextBlock extends AbstractTextBlock implements TextBlock { + private final TextBlock right; + private final TextBlock left; + private final TextBlock up; + private final TextBlock down; + private final GuideLine guideline; + + public DirectionalTextBlock(GuideLine guideline, TextBlock right, TextBlock left, TextBlock up, TextBlock down) { + this.right = right; + this.left = left; + this.up = up; + this.down = down; + this.guideline = guideline; + } + + public void drawU(UGraphic ug) { + Direction dir = guideline.getArrowDirection(); + switch (dir) { + case RIGHT: + right.drawU(ug); + break; + case LEFT: + left.drawU(ug); + break; + case UP: + up.drawU(ug); + break; + case DOWN: + down.drawU(ug); + break; + default: + throw new UnsupportedOperationException(); + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return right.calculateDimension(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/svek/GuideLine.java b/src/net/sourceforge/plantuml/svek/GuideLine.java new file mode 100644 index 000000000..b021f9c4e --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/GuideLine.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.svek; + +import net.sourceforge.plantuml.Direction; + +public interface GuideLine { + + public Direction getArrowDirection(); + +} diff --git a/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java b/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java index 77f9b49c3..554ddf7c9 100644 --- a/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java +++ b/src/net/sourceforge/plantuml/svek/InnerStateAutonom.java @@ -103,7 +103,7 @@ public final class InnerStateAutonom extends AbstractTextBlock implements IEntit } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index 354a1de1d..af6b8fb27 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -66,12 +66,11 @@ import net.sourceforge.plantuml.cucadiagram.LinkMiddleDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.cucadiagram.NoteLinkStrategy; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; -import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.descdiagram.command.StringWithArrow; 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.TextBlockArrow; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.graphic.USymbolFolder; @@ -99,9 +98,10 @@ import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorNone; import net.sourceforge.plantuml.ugraphic.color.HColorUtils; -public class Line implements Moveable, Hideable { +public class Line implements Moveable, Hideable, GuideLine { private static final Dimension2DDouble CONSTRAINT_SPOT = new Dimension2DDouble(10, 10); + private final Cluster ltail; private final Cluster lhead; private final Link link; @@ -151,64 +151,28 @@ public class Line implements Moveable, Hideable { return super.toString() + " color=" + lineColor; } - class DirectionalTextBlock extends AbstractTextBlock implements TextBlock { - - private final TextBlock right; - private final TextBlock left; - private final TextBlock up; - private final TextBlock down; - - DirectionalTextBlock(TextBlock right, TextBlock left, TextBlock up, TextBlock down) { - this.right = right; - this.left = left; - this.up = up; - this.down = down; + public Direction getArrowDirection() { + if (getLinkArrow() == LinkArrow.BACKWARD) { + return getArrowDirectionInternal().getInv(); } + return getArrowDirectionInternal(); + } - public void drawU(UGraphic ug) { - Direction dir = getDirection(); - if (getLinkArrow() == LinkArrow.BACKWARD) { - dir = dir.getInv(); - } - switch (dir) { - case RIGHT: - right.drawU(ug); - break; - case LEFT: - left.drawU(ug); - break; - case UP: - up.drawU(ug); - break; - case DOWN: - down.drawU(ug); - break; - default: - throw new UnsupportedOperationException(); - } + private Direction getArrowDirectionInternal() { + if (isAutolink()) { + final double startAngle = dotPath.getStartAngle(); + return Direction.LEFT; } - - public Dimension2D calculateDimension(StringBounder stringBounder) { - return right.calculateDimension(stringBounder); + final Point2D start = dotPath.getStartPoint(); + final Point2D end = dotPath.getEndPoint(); + final double ang = Math.atan2(end.getX() - start.getX(), end.getY() - start.getY()); + if (ang > -Math.PI / 4 && ang < Math.PI / 4) { + return Direction.DOWN; } - - private Direction getDirection() { - if (isAutolink()) { - final double startAngle = dotPath.getStartAngle(); - return Direction.LEFT; - } - final Point2D start = dotPath.getStartPoint(); - final Point2D end = dotPath.getEndPoint(); - final double ang = Math.atan2(end.getX() - start.getX(), end.getY() - start.getY()); - if (ang > -Math.PI / 4 && ang < Math.PI / 4) { - return Direction.DOWN; - } - if (ang > Math.PI * 3 / 4 || ang < -Math.PI * 3 / 4) { - return Direction.UP; - } - return end.getX() > start.getX() ? Direction.RIGHT : Direction.LEFT; + if (ang > Math.PI * 3 / 4 || ang < -Math.PI * 3 / 4) { + return Direction.UP; } - + return end.getX() > start.getX() ? Direction.RIGHT : Direction.LEFT; } private Cluster getCluster2(Bibliotekon bibliotekon, IEntity entityMutable) { @@ -221,7 +185,7 @@ public class Line implements Moveable, Hideable { } public Line(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder, - FontConfiguration labelFont, Bibliotekon bibliotekon, Pragma pragma) { + FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma) { if (link == null) { throw new IllegalArgumentException(); @@ -243,7 +207,7 @@ public class Line implements Moveable, Hideable { if (link.getColors() != null) { skinParam = link.getColors().mute(skinParam); - labelFont = labelFont.mute(link.getColors()); + font = font.mute(link.getColors()); } this.backgroundColor = skinParam.getBackgroundColor(false); this.defaultThickness = skinParam.getThickness(LineParam.arrow, null); @@ -263,37 +227,30 @@ public class Line implements Moveable, Hideable { this.startTailColor = colorSequence.getValue(); this.endHeadColor = colorSequence.getValue(); - final TextBlock labelOnly; + TextBlock labelOnly; if (Display.isNull(link.getLabel())) { - if (getLinkArrow() == LinkArrow.NONE) { - labelOnly = null; - } else { - final TextBlockArrow right = new TextBlockArrow(Direction.RIGHT, labelFont); - final TextBlockArrow left = new TextBlockArrow(Direction.LEFT, labelFont); - final TextBlockArrow up = new TextBlockArrow(Direction.UP, labelFont); - final TextBlockArrow down = new TextBlockArrow(Direction.DOWN, labelFont); - labelOnly = new DirectionalTextBlock(right, left, up, down); + labelOnly = TextBlockUtils.EMPTY_TEXT_BLOCK; + if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL) { + labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font); } } else { - final TextBlock label = getLineLabel(link, skinParam, labelFont); - if (getLinkArrow() == LinkArrow.NONE) { - labelOnly = label; + final HorizontalAlignment alignment = getMessageTextAlignment(link.getUmlDiagramType(), skinParam); + final boolean hasSeveralGuideLines = link.getLabel().hasSeveralGuideLines(); + final TextBlock block; + if (hasSeveralGuideLines) { + block = StringWithArrow.addSeveralMagicArrows(link.getLabel(), this, font, alignment, skinParam); } else { - TextBlock right = new TextBlockArrow(Direction.RIGHT, labelFont); - right = TextBlockUtils.mergeLR(label, right, VerticalAlignment.CENTER); - TextBlock left = new TextBlockArrow(Direction.LEFT, labelFont); - left = TextBlockUtils.mergeLR(left, label, VerticalAlignment.CENTER); - TextBlock up = new TextBlockArrow(Direction.UP, labelFont); - up = TextBlockUtils.mergeTB(up, label, HorizontalAlignment.CENTER); - TextBlock down = new TextBlockArrow(Direction.DOWN, labelFont); - down = TextBlockUtils.mergeTB(label, down, HorizontalAlignment.CENTER); - labelOnly = new DirectionalTextBlock(right, left, up, down); + block = link.getLabel().create9(font, alignment, skinParam, skinParam.maxMessageSize()); + } + labelOnly = addVisibilityModifier(block, link, skinParam); + if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL && hasSeveralGuideLines == false) { + labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font); } } final TextBlock noteOnly; if (link.getNote() == null) { - noteOnly = null; + noteOnly = TextBlockUtils.EMPTY_TEXT_BLOCK; } else { noteOnly = new EntityImageNoteLink(link.getNote(), link.getNoteColors(), skinParam, link.getStyleBuilder()); if (link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_NOT_PRINTED @@ -302,57 +259,43 @@ public class Line implements Moveable, Hideable { } } - if (labelOnly != null && noteOnly != null) { - if (link.getNotePosition() == Position.LEFT) { - labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER); - } else if (link.getNotePosition() == Position.RIGHT) { - labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER); - } else if (link.getNotePosition() == Position.TOP) { - labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER); - } else { - labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER); - } - } else if (labelOnly != null) { - labelText = labelOnly; - } else if (noteOnly != null) { - labelText = noteOnly; + if (link.getNotePosition() == Position.LEFT) { + labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER); + } else if (link.getNotePosition() == Position.RIGHT) { + labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER); + } else if (link.getNotePosition() == Position.TOP) { + labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER); } else { - labelText = null; + labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER); } if (link.getQualifier1() == null) { startTailText = null; } else { - startTailText = Display.getWithNewlines(link.getQualifier1()).create(labelFont, HorizontalAlignment.CENTER, + startTailText = Display.getWithNewlines(link.getQualifier1()).create(font, HorizontalAlignment.CENTER, skinParam); } if (link.getQualifier2() == null) { endHeadText = null; } else { - endHeadText = Display.getWithNewlines(link.getQualifier2()).create(labelFont, HorizontalAlignment.CENTER, + endHeadText = Display.getWithNewlines(link.getQualifier2()).create(font, HorizontalAlignment.CENTER, skinParam); } } - private TextBlock getLineLabel(Link link, ISkinParam skinParam, FontConfiguration labelFont) { - final double marginLabel = startUid.equalsId(endUid) ? 6 : 1; - final HorizontalAlignment alignment = getMessageTextAlignment(link.getUmlDiagramType(), skinParam); - TextBlock label = link.getLabel().create9(labelFont, alignment, skinParam, skinParam.maxMessageSize()); + private TextBlock addVisibilityModifier(TextBlock block, Link link, ISkinParam skinParam) { final VisibilityModifier visibilityModifier = link.getVisibilityModifier(); if (visibilityModifier != null) { final Rose rose = new Rose(); - // final HtmlColor back = visibilityModifier.getBackground() == null ? null : - // rose.getHtmlColor(skinParam, - // visibilityModifier.getBackground()); final HColor fore = rose.getHtmlColor(skinParam, visibilityModifier.getForeground()); TextBlock visibility = visibilityModifier.getUBlock(skinParam.classAttributeIconSize(), fore, null, false); visibility = TextBlockUtils.withMargin(visibility, 0, 1, 2, 0); - label = TextBlockUtils.mergeLR(visibility, label, VerticalAlignment.CENTER); + block = TextBlockUtils.mergeLR(visibility, block, VerticalAlignment.CENTER); } - label = TextBlockUtils.withMargin(label, marginLabel, marginLabel); - return label; + final double marginLabel = startUid.equalsId(endUid) ? 6 : 1; + return TextBlockUtils.withMargin(block, marginLabel, marginLabel); } private HorizontalAlignment getMessageTextAlignment(UmlDiagramType umlDiagramType, ISkinParam skinParam) { @@ -363,7 +306,7 @@ public class Line implements Moveable, Hideable { } public boolean hasNoteLabelText() { - return labelText != null; + return labelText != null && labelText != TextBlockUtils.EMPTY_TEXT_BLOCK; } private LinkArrow getLinkArrow() { @@ -405,15 +348,15 @@ public class Line implements Moveable, Hideable { sb.append(","); } sb.append("color=\"" + DotStringFactory.sharp000000(lineColor) + "\""); - if (labelText != null || link.getLinkConstraint() != null) { + if (hasNoteLabelText() || link.getLinkConstraint() != null) { sb.append(","); if (graphvizVersion.useXLabelInsteadOfLabel() || dotMode == DotMode.NO_LEFT_RIGHT_AND_XLABEL) { sb.append("xlabel=<"); } else { sb.append("label=<"); } - final Dimension2D dimNote = labelText == null ? CONSTRAINT_SPOT - : labelText.calculateDimension(stringBounder); + final Dimension2D dimNote = hasNoteLabelText() ? labelText.calculateDimension(stringBounder) + : CONSTRAINT_SPOT; appendTable(sb, eventuallyDivideByTwo(dimNote), noteLabelColor, graphvizVersion); sb.append(">"); } @@ -614,12 +557,12 @@ public class Line implements Moveable, Hideable { } - if (this.labelText != null || link.getLinkConstraint() != null) { + if (hasNoteLabelText() || link.getLinkConstraint() != null) { final Point2D pos = getXY(fullSvg, this.noteLabelColor); if (pos != null) { corner1.manage(pos); - this.labelXY = labelText == null ? TextBlockUtils.asPositionable(CONSTRAINT_SPOT, stringBounder, pos) - : TextBlockUtils.asPositionable(labelText, stringBounder, pos); + this.labelXY = hasNoteLabelText() ? TextBlockUtils.asPositionable(labelText, stringBounder, pos) + : TextBlockUtils.asPositionable(CONSTRAINT_SPOT, stringBounder, pos); } } @@ -741,7 +684,7 @@ public class Line implements Moveable, Hideable { ug = ug.apply(new UStroke()).apply(color); - if (this.labelText != null && this.labelXY != null + if (hasNoteLabelText() && this.labelXY != null && link.getNoteLinkStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED) { this.labelText.drawU(ug.apply( new UTranslate(x + this.labelXY.getPosition().getX(), y + this.labelXY.getPosition().getY()))); @@ -766,7 +709,7 @@ public class Line implements Moveable, Hideable { } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } if (link.getLinkConstraint() != null) { @@ -847,8 +790,7 @@ public class Line implements Moveable, Hideable { } int i = 0; for (Colors colors : supplementaryColors) { - ug.apply(new UTranslate(2 * (i + 1), 2 * (i + 1))).apply(colors.getColor(ColorType.LINE)) - .draw(todraw); + ug.apply(new UTranslate(2 * (i + 1), 2 * (i + 1))).apply(colors.getColor(ColorType.LINE)).draw(todraw); i++; } } @@ -874,7 +816,7 @@ public class Line implements Moveable, Hideable { } else { return 0; } - if (labelText != null) { + if (hasNoteLabelText()) { strategy.eat(labelText.calculateDimension(stringBounder).getWidth()); } if (startTailText != null) { @@ -898,7 +840,7 @@ public class Line implements Moveable, Hideable { return 0; } final ArithmeticStrategy strategy = new ArithmeticStrategySum(); - if (labelText != null) { + if (hasNoteLabelText()) { strategy.eat(labelText.calculateDimension(stringBounder).getHeight()); } if (startTailText != null) { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java b/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java index 2e49f0727..490a48780 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java @@ -115,7 +115,7 @@ public class EntityImageActivity extends AbstractEntityImage { throw new UnsupportedOperationException(); } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java index a4132b3db..43b40d17e 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java @@ -130,7 +130,7 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi drawInternal(ug); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java index b0388004c..025882641 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageDescription.java @@ -291,7 +291,7 @@ public class EntityImageDescription extends AbstractEntityImage { } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java index 5873b80ad..c8456d28d 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java @@ -138,7 +138,7 @@ public class EntityImageEmptyPackage extends AbstractEntityImage { getSkinParam().getStereotypeAlignment()); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java index abeaea706..6397d0f35 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterface.java @@ -103,7 +103,7 @@ public class EntityImageLollipopInterface extends AbstractEntityImage { final double y = SIZE; desc.drawU(ug.apply(new UTranslate(x, y))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java index 95c29d589..9ce7ad939 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java @@ -121,7 +121,7 @@ public class EntityImageLollipopInterfaceEye1 extends AbstractEntityImage { // final double y = SIZE; // desc.drawU(ug.apply(new UTranslate(x, y))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java index f014039c9..0ed037036 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java @@ -132,7 +132,7 @@ public class EntityImageLollipopInterfaceEye2 extends AbstractEntityImage { stereo.drawU(ug.apply(new UTranslate(x2, y2))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageMap.java b/src/net/sourceforge/plantuml/svek/image/EntityImageMap.java index ed6b6cddb..53ed8a977 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageMap.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageMap.java @@ -165,7 +165,7 @@ public class EntityImageMap extends AbstractEntityImage implements Stencil, With entries.drawU(ug2.apply(UTranslate.dy(dimTitle.getHeight()))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java index 1044cb6a6..d8397af91 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java @@ -233,7 +233,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { opale.drawU(Colors.applyStroke(stroked, getEntity().getColors(skinParam))); } if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java index 3d371eb16..522f17574 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageObject.java @@ -163,7 +163,7 @@ public class EntityImageObject extends AbstractEntityImage implements Stencil { fields.drawU(ug2.apply(UTranslate.dy(dimTitle.getHeight()))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageState.java b/src/net/sourceforge/plantuml/svek/image/EntityImageState.java index 148f33479..768a7910e 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageState.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageState.java @@ -116,6 +116,7 @@ public class EntityImageState extends AbstractEntityImage { } final public void drawU(UGraphic ug) { + ug.startGroup(getEntity().getIdent().getName()); if (url != null) { ug.startUrl(url); } @@ -163,8 +164,9 @@ public class EntityImageState extends AbstractEntityImage { fields.drawU(ug.apply(new UTranslate(xFields, yFields))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } + ug.closeGroup(); } private UStroke getStroke() { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java index 7da11dcc6..ecea657e0 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java @@ -114,7 +114,7 @@ public class EntityImageState2 extends AbstractEntityImage { asSmall.drawU(ug); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java b/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java index 1360a3797..17156432f 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageStateEmptyDescription.java @@ -120,7 +120,7 @@ public class EntityImageStateEmptyDescription extends AbstractEntityImage { desc.drawU(ug.apply(new UTranslate(xDesc, yDesc))); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java index 4ef098c60..5830db4d6 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java @@ -140,7 +140,7 @@ public class EntityImageUseCase extends AbstractEntityImage { ellipse.drawU(ug2); if (url != null) { - ug.closeAction(); + ug.closeUrl(); } } diff --git a/src/net/sourceforge/plantuml/svek/image/Footprint.java b/src/net/sourceforge/plantuml/svek/image/Footprint.java index 827ddfe46..5ebbcb37a 100644 --- a/src/net/sourceforge/plantuml/svek/image/Footprint.java +++ b/src/net/sourceforge/plantuml/svek/image/Footprint.java @@ -45,6 +45,7 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicNo; import net.sourceforge.plantuml.ugraphic.UHorizontalLine; import net.sourceforge.plantuml.ugraphic.UImage; import net.sourceforge.plantuml.ugraphic.ULine; @@ -68,7 +69,7 @@ public class Footprint { } - class MyUGraphic implements UGraphic { + class MyUGraphic extends UGraphicNo implements UGraphic { private final UTranslate translate; private final List all; @@ -130,12 +131,6 @@ public class Footprint { return new ColorMapperIdentity(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - private void addPoint(double x, double y) { all.add(new Point2D.Double(x, y)); } diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index 4cd9f3396..d88ec0748 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -45,6 +45,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.xml.parsers.DocumentBuilder; @@ -64,7 +66,6 @@ import org.w3c.dom.Element; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.SignatureUtils; -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.SvgString; import net.sourceforge.plantuml.code.Base64Coder; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; @@ -175,8 +176,8 @@ public class SvgGraphics { private Element pendingBackground; public void paintBackcolorGradient(ColorMapper mapper, HColorGradient gr) { - final String id = createSvgGradient(mapper.toHtml(gr.getColor1()), - mapper.toHtml(gr.getColor2()), gr.getPolicy()); + final String id = createSvgGradient(mapper.toHtml(gr.getColor1()), mapper.toHtml(gr.getColor2()), + gr.getPolicy()); setFillColor("url(#" + id + ")"); setStrokeColor(null); pendingBackground = createRectangleInternal(0, 0, 0, 0); @@ -309,49 +310,8 @@ public class SvgGraphics { this.strokeDasharray = strokeDasharray; } - public void closeLink() { - if (pendingAction.size() > 0) { - final Element element = pendingAction.get(0); - pendingAction.remove(0); - if (element.getFirstChild() != null) { - // Empty link - getG().appendChild(element); - } - } - } - private final List pendingAction = new ArrayList(); - public void openLink(String url, String title, String target) { - if (url == null) { - throw new IllegalArgumentException(); - } - // javascript: security issue - if (GraphvizUtils.getJavascriptUnsecure() == false && url.toLowerCase().startsWith("javascript")) { - return; - } - - if (pendingAction.size() > 0) { - closeLink(); - } - - pendingAction.add(0, (Element) document.createElement("a")); - pendingAction.get(0).setAttribute("target", target); - pendingAction.get(0).setAttribute(XLINK_HREF1, url); - pendingAction.get(0).setAttribute(XLINK_HREF2, url); - pendingAction.get(0).setAttribute("xlink:type", "simple"); - pendingAction.get(0).setAttribute("xlink:actuate", "onRequest"); - pendingAction.get(0).setAttribute("xlink:show", "new"); - if (title == null) { - pendingAction.get(0).setAttribute(XLINK_TITLE1, url); - pendingAction.get(0).setAttribute(XLINK_TITLE2, url); - } else { - title = title.replaceAll("\\\\n", "\n"); - pendingAction.get(0).setAttribute(XLINK_TITLE1, title); - pendingAction.get(0).setAttribute(XLINK_TITLE2, title); - } - } - public final Element getG() { if (pendingAction.size() == 0) { return gRoot; @@ -832,4 +792,69 @@ public class SvgGraphics { getG().appendChild(commentElement); } + public void openLink(String url, String title, String target) { + if (url == null) { + throw new IllegalArgumentException(); + } + // javascript: security issue + if (GraphvizUtils.getJavascriptUnsecure() == false && url.toLowerCase().startsWith("javascript")) { + return; + } + +// if (pendingAction.size() > 0) { +// closeLink(); +// } + + pendingAction.add(0, (Element) document.createElement("a")); + pendingAction.get(0).setAttribute("target", target); + pendingAction.get(0).setAttribute(XLINK_HREF1, url); + pendingAction.get(0).setAttribute(XLINK_HREF2, url); + pendingAction.get(0).setAttribute("xlink:type", "simple"); + pendingAction.get(0).setAttribute("xlink:actuate", "onRequest"); + pendingAction.get(0).setAttribute("xlink:show", "new"); + if (title == null) { + pendingAction.get(0).setAttribute(XLINK_TITLE1, url); + pendingAction.get(0).setAttribute(XLINK_TITLE2, url); + } else { + title = formatTitle(title); + pendingAction.get(0).setAttribute(XLINK_TITLE1, title); + pendingAction.get(0).setAttribute(XLINK_TITLE2, title); + } + } + + private String formatTitle(String title) { + final Pattern p = Pattern.compile("\\"); + final Matcher m = p.matcher(title); + final StringBuffer sb = new StringBuffer(); + while (m.find()) { + final String num = m.group(1); + final char c = (char) Integer.parseInt(num, 16); + m.appendReplacement(sb, "" + c); + } + m.appendTail(sb); + + title = sb.toString().replaceAll("\\\\n", "\n"); + return title; + } + + public void closeLink() { + if (pendingAction.size() > 0) { + final Element element = pendingAction.get(0); + pendingAction.remove(0); + if (element.getFirstChild() != null) { + // Empty link + getG().appendChild(element); + } + } + } + + public void startGroup(String groupId) { + pendingAction.add(0, (Element) document.createElement("g")); + pendingAction.get(0).setAttribute("id", groupId); + } + + public void closeGroup() { + closeLink(); + } + } diff --git a/src/net/sourceforge/plantuml/tim/Eater.java b/src/net/sourceforge/plantuml/tim/Eater.java index a5bc1b809..bb6fa985d 100644 --- a/src/net/sourceforge/plantuml/tim/Eater.java +++ b/src/net/sourceforge/plantuml/tim/Eater.java @@ -50,25 +50,19 @@ public abstract class Eater { private int i = 0; private final String s; - private final StringLocated sl; + private final LineLocation lineLocation; public Eater(StringLocated sl) { - this.s = sl.getString(); - this.sl = sl; + this(sl.getString(), sl.getLocation()); } - public final StringLocated getStringLocated() { - if (sl == null) { - throw new UnsupportedOperationException(); - } - return sl; + protected Eater(String s, LineLocation lineLocation) { + this.s = s; + this.lineLocation = lineLocation; } public final LineLocation getLineLocation() { - if (sl == null) { - throw new UnsupportedOperationException(); - } - return sl.getLocation(); + return lineLocation; } public abstract void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated; @@ -100,7 +94,7 @@ public abstract class Eater { final TokenStack tokenStack = new TokenStack(); addIntoTokenStack(tokenStack, false); if (tokenStack.size() == 0) { - throw EaterException.located("Missing expression", getStringLocated()); + throw EaterException.located("Missing expression"); } return tokenStack; } @@ -126,7 +120,7 @@ public abstract class Eater { final public String eatAndGetQuotedString() throws EaterException { final char separator = peekChar(); if (TLineType.isQuote(separator) == false) { - throw EaterException.located("quote10", getStringLocated()); + throw EaterException.located("quote10"); } checkAndEatChar(separator); final StringBuilder value = new StringBuilder(); @@ -147,7 +141,7 @@ public abstract class Eater { while (true) { char ch = peekChar(); if (ch == 0) { - throw EaterException.located("until001", getStringLocated()); + throw EaterException.located("until001"); } if (level == 0 && (ch == ',' || ch == ')')) { return value.toString().trim(); @@ -190,7 +184,7 @@ public abstract class Eater { final protected String eatAndGetVarname() throws EaterException { final StringBuilder varname = new StringBuilder("" + eatOneChar()); if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) { - throw EaterException.located("a002", getStringLocated()); + throw EaterException.located("a002"); } addUpToLastLetterOrUnderscoreOrDigit(varname); return varname.toString(); @@ -199,7 +193,7 @@ public abstract class Eater { final protected String eatAndGetFunctionName() throws EaterException { final StringBuilder varname = new StringBuilder("" + eatOneChar()); if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) { - throw EaterException.located("a003", getStringLocated()); + throw EaterException.located("a003"); } addUpToLastLetterOrUnderscoreOrDigit(varname); return varname.toString(); @@ -243,7 +237,7 @@ public abstract class Eater { final protected void checkAndEatChar(char ch) throws EaterException { if (i >= s.length() || s.charAt(i) != ch) { - throw EaterException.located("a001", getStringLocated()); + throw EaterException.located("a001"); } i++; } @@ -314,7 +308,7 @@ public abstract class Eater { if (allowNoParenthesis) { return new TFunctionImpl(functionName, args, unquoted, type); } - throw EaterException.located("Missing opening parenthesis", getStringLocated()); + throw EaterException.located("Missing opening parenthesis"); } while (true) { skipSpaces(); @@ -339,7 +333,7 @@ public abstract class Eater { checkAndEatChar(")"); break; } else { - throw EaterException.located("Error in function definition", getStringLocated()); + throw EaterException.located("Error in function definition"); } } skipSpaces(); @@ -348,7 +342,8 @@ public abstract class Eater { final protected TFunctionImpl eatDeclareReturnFunctionWithOptionalReturn(TContext context, TMemory memory, boolean unquoted, LineLocation location) throws EaterException, EaterExceptionLocated { - final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false, TFunctionType.RETURN_FUNCTION); + final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false, + TFunctionType.RETURN_FUNCTION); if (peekChar() == 'r') { checkAndEatChar("return"); skipSpaces(); @@ -365,7 +360,8 @@ public abstract class Eater { final protected TFunctionImpl eatDeclareProcedure(TContext context, TMemory memory, boolean unquoted, LineLocation location) throws EaterException, EaterExceptionLocated { - final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false, TFunctionType.PROCEDURE); + final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false, + TFunctionType.PROCEDURE); return result; } diff --git a/src/net/sourceforge/plantuml/tim/EaterAssert.java b/src/net/sourceforge/plantuml/tim/EaterAssert.java index 68bf5a864..39a5b6b20 100644 --- a/src/net/sourceforge/plantuml/tim/EaterAssert.java +++ b/src/net/sourceforge/plantuml/tim/EaterAssert.java @@ -55,9 +55,9 @@ public class EaterAssert extends Eater { if (ch == ':') { checkAndEatChar(':'); final TValue message = eatExpression(context, memory); - throw EaterException.located("Assertion error : " + message.toString(), getStringLocated()); + throw EaterException.located("Assertion error : " + message.toString()); } - throw EaterException.located("Assertion error", getStringLocated()); + throw EaterException.located("Assertion error"); } } diff --git a/src/net/sourceforge/plantuml/tim/EaterException.java b/src/net/sourceforge/plantuml/tim/EaterException.java index c32d6a1de..750d82c6a 100644 --- a/src/net/sourceforge/plantuml/tim/EaterException.java +++ b/src/net/sourceforge/plantuml/tim/EaterException.java @@ -48,7 +48,7 @@ public class EaterException extends Exception { return new EaterException(message); } - public static EaterException located(String message, StringLocated unused) { + public static EaterException located(String message) { return unlocated(message); } diff --git a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java index f8e654253..17ade9ded 100644 --- a/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java +++ b/src/net/sourceforge/plantuml/tim/EaterFunctionCall.java @@ -36,7 +36,9 @@ package net.sourceforge.plantuml.tim; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.tim.expression.TValue; @@ -45,6 +47,7 @@ import net.sourceforge.plantuml.tim.expression.TokenStack; public class EaterFunctionCall extends Eater { private final List values = new ArrayList(); + private final Map namedArguments = new HashMap(); private final boolean isLegacyDefine; private final boolean unquoted; @@ -65,18 +68,30 @@ public class EaterFunctionCall extends Eater { } while (true) { skipSpaces(); - if (isLegacyDefine || unquoted) { - final String tmp = eatAndGetOptionalQuotedString(); - final String tmp2 = context.applyFunctionsAndVariables(memory, getLineLocation(), tmp); - // final TVariable var = memory.getVariable(tmp); - // final TValue result = var == null ? TValue.fromString(tmp) : var.getValue2(); - final TValue result = TValue.fromString(tmp2); + if (isLegacyDefine) { + final String read = eatAndGetOptionalQuotedString(); + final String value = context.applyFunctionsAndVariables(memory, getLineLocation(), read); + final TValue result = TValue.fromString(value); values.add(result); + } else if (unquoted) { + final String read = eatAndGetOptionalQuotedString(); + if (TokenStack.isSpecialAffectationWhenFunctionCall(read)) { + updateNamedArguments(read, context, memory); + } else { + final String value = context.applyFunctionsAndVariables(memory, getLineLocation(), read); + final TValue result = TValue.fromString(value); + values.add(result); + } } else { final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace(); - tokens.guessFunctions(); - final TValue result = tokens.getResult(getLineLocation(), context, memory); - values.add(result); + if (tokens.isSpecialAffectationWhenFunctionCall()) { + final String special = tokens.tokenIterator().nextToken().getSurface(); + updateNamedArguments(special, context, memory); + } else { + tokens.guessFunctions(); + final TValue result = tokens.getResult(getLineLocation(), context, memory); + values.add(result); + } } skipSpaces(); final char ch = eatOneChar(); @@ -86,14 +101,28 @@ public class EaterFunctionCall extends Eater { if (ch == ')') { break; } - throw EaterException.located("call001", getStringLocated()); + throw EaterException.located("call001"); } } + private void updateNamedArguments(String special, TContext context, TMemory memory) + throws EaterException, EaterExceptionLocated { + assert special.contains("="); + final StringEater stringEater = new StringEater(special); + final String varname = stringEater.eatAndGetVarname(); + stringEater.checkAndEatChar('='); + final TValue expr = stringEater.eatExpression(context, memory); + namedArguments.put(varname, expr); + } + public final List getValues() { return Collections.unmodifiableList(values); } + public final Map getNamedArguments() { + return Collections.unmodifiableMap(namedArguments); + } + public final String getEndOfLine() throws EaterException { return this.eatAllToEnd(); } diff --git a/src/net/sourceforge/plantuml/tim/EaterStartsub.java b/src/net/sourceforge/plantuml/tim/EaterStartsub.java index 7cf20a22e..6fb385214 100644 --- a/src/net/sourceforge/plantuml/tim/EaterStartsub.java +++ b/src/net/sourceforge/plantuml/tim/EaterStartsub.java @@ -51,7 +51,7 @@ public class EaterStartsub extends Eater { skipSpaces(); this.subname = eatAllToEnd(); if (this.subname.matches("\\w+") == false) { - throw EaterException.located("Bad sub name", getStringLocated()); + throw EaterException.located("Bad sub name"); } } diff --git a/src/net/sourceforge/plantuml/tim/FunctionsSet.java b/src/net/sourceforge/plantuml/tim/FunctionsSet.java index 70bb7835f..62c2e80ce 100644 --- a/src/net/sourceforge/plantuml/tim/FunctionsSet.java +++ b/src/net/sourceforge/plantuml/tim/FunctionsSet.java @@ -55,10 +55,10 @@ public class FunctionsSet { return func; } for (TFunction candidate : this.functions.values()) { - if (candidate.getSignature().sameNameAs(searched) == false) { + if (candidate.getSignature().sameFunctionNameAs(searched) == false) { continue; } - if (candidate.canCover(searched.getNbArg())) { + if (candidate.canCover(searched.getNbArg(), searched.getNamedArguments())) { return candidate; } } @@ -97,7 +97,7 @@ public class FunctionsSet { public void executeLegacyDefine(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { if (this.pendingFunction != null) { - throw EaterException.located("already0048", s); + throw EaterException.located("already0048"); } final EaterLegacyDefine legacyDefine = new EaterLegacyDefine(s); legacyDefine.analyze(context, memory); @@ -109,7 +109,7 @@ public class FunctionsSet { public void executeLegacyDefineLong(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { if (this.pendingFunction != null) { - throw EaterException.located("already0068", s); + throw EaterException.located("already0068"); } final EaterLegacyDefineLong legacyDefineLong = new EaterLegacyDefineLong(s); legacyDefineLong.analyze(context, memory); @@ -119,7 +119,7 @@ public class FunctionsSet { public void executeDeclareReturnFunction(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { if (this.pendingFunction != null) { - throw EaterException.located("already0068", s); + throw EaterException.located("already0068"); } final EaterDeclareReturnFunction declareFunction = new EaterDeclareReturnFunction(s); declareFunction.analyze(context, memory); @@ -127,7 +127,7 @@ public class FunctionsSet { final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature(); final TFunction previous = this.functions.get(declaredSignature); if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) { - throw EaterException.located("This function is already defined", s); + throw EaterException.located("This function is already defined"); } if (finalFlag) { this.functionsFinal.add(declaredSignature); @@ -142,7 +142,7 @@ public class FunctionsSet { public void executeDeclareProcedure(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { if (this.pendingFunction != null) { - throw EaterException.located("already0068", s); + throw EaterException.located("already0068"); } final EaterDeclareProcedure declareFunction = new EaterDeclareProcedure(s); declareFunction.analyze(context, memory); @@ -150,7 +150,7 @@ public class FunctionsSet { final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature(); final TFunction previous = this.functions.get(declaredSignature); if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) { - throw EaterException.located("This function is already defined", s); + throw EaterException.located("This function is already defined"); } if (finalFlag) { this.functionsFinal.add(declaredSignature); diff --git a/src/net/sourceforge/plantuml/tim/StringEater.java b/src/net/sourceforge/plantuml/tim/StringEater.java new file mode 100644 index 000000000..7a8fa9fc9 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/StringEater.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.tim; + +public class StringEater extends Eater { + + public StringEater(String s) { + super(s, null); + } + + @Override + public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index 8f43eb6f4..4950ab75a 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -267,7 +267,7 @@ public class TContext { if (e instanceof EaterExceptionLocated) throw (EaterExceptionLocated) e; e.printStackTrace(); - throw EaterException.located("Fatal parsing error", s); + throw EaterException.located("Fatal parsing error"); } } @@ -324,7 +324,7 @@ public class TContext { } else if (s.getString().matches("^\\s+$")) { return null; } else { - throw EaterException.located("Compile Error " + ftype + " " + type, s); + throw EaterException.located("Compile Error " + ftype + " " + type); } } @@ -396,11 +396,11 @@ public class TContext { final EaterFunctionCall call = new EaterFunctionCall(new StringLocated(sub, location), isLegacyDefine(presentFunction), isUnquoted(presentFunction)); call.analyze(this, memory); - final TFunction function = functionsSet - .getFunctionSmart(new TFunctionSignature(presentFunction, call.getValues().size())); + final TFunctionSignature signature = new TFunctionSignature(presentFunction, call.getValues().size(), + call.getNamedArguments().keySet()); + final TFunction function = functionsSet.getFunctionSmart(signature); if (function == null) { - throw EaterException.located("Function not found " + presentFunction, - new StringLocated(str, location)); + throw EaterException.located("Function not found " + presentFunction); } if (function.getFunctionType() == TFunctionType.PROCEDURE) { this.pendingAdd = result.toString(); @@ -414,7 +414,8 @@ public class TContext { } assert function.getFunctionType() == TFunctionType.RETURN_FUNCTION || function.getFunctionType() == TFunctionType.LEGACY_DEFINE; - final TValue functionReturn = function.executeReturnFunction(this, memory, location, call.getValues()); + final TValue functionReturn = function.executeReturnFunction(this, memory, location, call.getValues(), + call.getNamedArguments()); result.append(functionReturn.toString()); i += call.getCurrentPosition() - 1; } else if (new VariableManager(this, memory, location).getVarnameAt(str, i) != null) { @@ -444,10 +445,10 @@ public class TContext { } } catch (IOException e) { e.printStackTrace(); - throw EaterException.located("Cannot import " + e.getMessage(), s); + throw EaterException.located("Cannot import " + e.getMessage()); } - throw EaterException.located("Cannot import", s); + throw EaterException.located("Cannot import"); } private void executeLog(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { @@ -478,14 +479,14 @@ public class TContext { } } catch (IOException e) { e.printStackTrace(); - throw EaterException.located("cannot include " + e, s); + throw EaterException.located("cannot include " + e); } } if (sub == null) { sub = subs.get(location); } if (sub == null) { - throw EaterException.located("cannot include " + location, s); + throw EaterException.located("cannot include " + location); } executeLinesInternal(memory, sub.lines(), null); } finally { @@ -514,7 +515,7 @@ public class TContext { } while (true); } catch (IOException e) { e.printStackTrace(); - throw EaterException.located("" + e, s); + throw EaterException.located("" + e); } } @@ -547,7 +548,7 @@ public class TContext { return; } if (strategy == PreprocessorIncludeStrategy.ONCE && filesUsedCurrent.contains(f2)) { - throw EaterException.located("This file has already been included", s); + throw EaterException.located("This file has already been included"); } if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) { @@ -555,7 +556,7 @@ public class TContext { } else { final Reader reader = f2.getReader(charset); if (reader == null) { - throw EaterException.located("Cannot include file", s); + throw EaterException.located("Cannot include file"); } reader2 = ReadLineReader.create(reader, location, s.getLocation()); } @@ -584,10 +585,10 @@ public class TContext { } } catch (IOException e) { e.printStackTrace(); - throw EaterException.located("cannot include " + e, s); + throw EaterException.located("cannot include " + e); } - throw EaterException.located("cannot include " + location, s); + throw EaterException.located("cannot include " + location); } public boolean isLegacyDefine(String functionName) { diff --git a/src/net/sourceforge/plantuml/tim/TFunction.java b/src/net/sourceforge/plantuml/tim/TFunction.java index f322629dd..4f513d25e 100644 --- a/src/net/sourceforge/plantuml/tim/TFunction.java +++ b/src/net/sourceforge/plantuml/tim/TFunction.java @@ -35,6 +35,8 @@ package net.sourceforge.plantuml.tim; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.expression.TValue; @@ -43,15 +45,18 @@ public interface TFunction { public TFunctionSignature getSignature(); - public boolean canCover(int nbArg); + public boolean canCover(int nbArg, Set namedArguments); public TFunctionType getFunctionType(); - public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) throws EaterException, EaterExceptionLocated; + public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) + throws EaterException, EaterExceptionLocated; - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException, EaterExceptionLocated; + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args, Map named) + throws EaterException, EaterExceptionLocated; - public void executeProcedureInternal(TContext context, TMemory memory, List args) throws EaterException, EaterExceptionLocated; + public void executeProcedureInternal(TContext context, TMemory memory, List args, Map named) + throws EaterException, EaterExceptionLocated; public boolean isUnquoted(); diff --git a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java index 9b9f08b02..62bf46f58 100644 --- a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java +++ b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java @@ -35,10 +35,12 @@ package net.sourceforge.plantuml.tim; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringLocated; @@ -56,24 +58,63 @@ public class TFunctionImpl implements TFunction { public TFunctionImpl(String functionName, List args, boolean unquoted, TFunctionType functionType) { - this.signature = new TFunctionSignature(functionName, args.size()); + final Set names = new HashSet(); + for (TFunctionArgument tmp : args) { + names.add(tmp.getName()); + } + this.signature = new TFunctionSignature(functionName, args.size(), names); this.args = args; this.unquoted = unquoted; this.functionType = functionType; } - 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) { + public boolean canCover(int nbArg, Set namedArguments) { + for (String n : namedArguments) { + if (signature.getNamedArguments().contains(n) == false) { return false; } } + if (nbArg > args.size()) { + return false; + } + assert nbArg <= args.size(); + int neededArgument = 0; + for (TFunctionArgument arg : args) { + if (namedArguments.contains(arg.getName())) { + continue; + } + if (arg.getOptionalDefaultValue() == null) { + neededArgument++; + } + } + if (nbArg < neededArgument) { + return false; + } + assert nbArg >= neededArgument; return true; } + private TMemory getNewMemory(TMemory memory, List values, Map namedArguments) { + final Map result = new HashMap(); + int ivalue = 0; + for (TFunctionArgument arg : args) { + final TValue value; + if (namedArguments.containsKey(arg.getName())) { + value = namedArguments.get(arg.getName()); + } else if (ivalue < values.size()) { + value = values.get(ivalue); + ivalue++; + } else { + value = arg.getOptionalDefaultValue(); + } + if (value == null) { + throw new IllegalStateException(); + } + result.put(arg.getName(), value); + } + return memory.forkFromGlobal(result); + } + @Override public String toString() { return "FUNCTION " + signature + " " + args; @@ -84,8 +125,8 @@ public class TFunctionImpl implements TFunction { if (s.getType() == TLineType.RETURN) { this.containsReturn = true; if (functionType == TFunctionType.PROCEDURE) { - throw EaterExceptionLocated.located( - "A procedure cannot have !return directive. Declare it as a function instead ?", s); + throw EaterExceptionLocated + .located("A procedure cannot have !return directive. Declare it as a function instead ?", s); // this.functionType = TFunctionType.RETURN; } } @@ -98,38 +139,29 @@ public class TFunctionImpl implements TFunction { call.analyze(context, memory); final String endOfLine = call.getEndOfLine(); final List args = call.getValues(); - executeProcedureInternal(context, memory, args); + final Map named = call.getNamedArguments(); + executeProcedureInternal(context, memory, args, named); context.appendEndOfLine(endOfLine); } - public void executeProcedureInternal(TContext context, TMemory memory, List args) + public void executeProcedureInternal(TContext context, TMemory memory, List args, Map named) throws EaterException, EaterExceptionLocated { if (functionType != TFunctionType.PROCEDURE && functionType != TFunctionType.LEGACY_DEFINELONG) { throw new IllegalStateException(); } - final TMemory copy = getNewMemory(memory, args); + final TMemory copy = getNewMemory(memory, args, named); context.executeLines(copy, body, TFunctionType.PROCEDURE, false); } - private TMemory getNewMemory(TMemory memory, List values) { - final Map foo = new HashMap(); - for (int i = 0; i < args.size(); i++) { - final TValue tmp = i < values.size() ? values.get(i) : args.get(i).getOptionalDefaultValue(); - foo.put(args.get(i).getName(), tmp); - } - final TMemory copy = memory.forkFromGlobal(foo); - return copy; - } - - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) - throws EaterException, EaterExceptionLocated { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args, + Map named) throws EaterException, EaterExceptionLocated { if (functionType == TFunctionType.LEGACY_DEFINE) { return executeReturnLegacyDefine(location, context, memory, args); } if (functionType != TFunctionType.RETURN_FUNCTION) { throw EaterException.unlocated("Illegal call here. Is there a return directive in your function?"); } - final TMemory copy = getNewMemory(memory, args); + final TMemory copy = getNewMemory(memory, args, named); final TValue result = context.executeLines(copy, body, TFunctionType.RETURN_FUNCTION, true); if (result == null) { throw EaterException.unlocated("No return directive found in your function"); @@ -142,7 +174,7 @@ public class TFunctionImpl implements TFunction { if (legacyDefinition == null) { throw new IllegalStateException(); } - final TMemory copy = getNewMemory(memory, args); + final TMemory copy = getNewMemory(memory, args, Collections.emptyMap()); final String tmp = context.applyFunctionsAndVariables(copy, location, legacyDefinition); if (tmp == null) { return TValue.fromString(""); diff --git a/src/net/sourceforge/plantuml/tim/TFunctionSignature.java b/src/net/sourceforge/plantuml/tim/TFunctionSignature.java index c0b9ad768..7e82b683b 100644 --- a/src/net/sourceforge/plantuml/tim/TFunctionSignature.java +++ b/src/net/sourceforge/plantuml/tim/TFunctionSignature.java @@ -34,26 +34,35 @@ */ package net.sourceforge.plantuml.tim; +import java.util.Collections; +import java.util.Set; + public class TFunctionSignature { private final String functionName; private final int nbArg; + private final Set namedArguments; public TFunctionSignature(String functionName, int nbArg) { + this(functionName, nbArg, Collections.emptySet()); + } + + public TFunctionSignature(String functionName, int nbArg, Set namedArguments) { if (functionName == null) { throw new IllegalArgumentException(); } this.functionName = functionName; this.nbArg = nbArg; + this.namedArguments = namedArguments; } - - public boolean sameNameAs(TFunctionSignature other) { + + public boolean sameFunctionNameAs(TFunctionSignature other) { return getFunctionName().equals(other.getFunctionName()); } @Override public String toString() { - return functionName + "/" + nbArg; + return functionName + "/" + nbArg + " " + namedArguments; } @Override @@ -78,4 +87,8 @@ public class TFunctionSignature { public final int getNbArg() { return nbArg; } + + public final Set getNamedArguments() { + return namedArguments; + } } diff --git a/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java b/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java index 0d729012d..04a723ac5 100644 --- a/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java +++ b/src/net/sourceforge/plantuml/tim/expression/ReversePolishInterpretor.java @@ -36,6 +36,7 @@ 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.List; @@ -96,7 +97,7 @@ public class ReversePolishInterpretor { if (function == null) { throw EaterException.unlocated("Unknow built-in function " + token2.getSurface()); } - if (function.canCover(nb) == false) { + if (function.canCover(nb, Collections.emptySet()) == false) { throw EaterException .unlocated("Bad number of arguments for " + function.getSignature().getFunctionName()); } @@ -109,7 +110,8 @@ public class ReversePolishInterpretor { if (location == null) { throw EaterException.unlocated("rpn44"); } - final TValue r = function.executeReturnFunction(context, memory, location, args); + final TValue r = function.executeReturnFunction(context, memory, location, args, + Collections.emptyMap()); if (trace) System.err.println("r=" + r); stack.addFirst(r); diff --git a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java index c61991a91..071a71014 100644 --- a/src/net/sourceforge/plantuml/tim/expression/TokenStack.java +++ b/src/net/sourceforge/plantuml/tim/expression/TokenStack.java @@ -47,12 +47,40 @@ import net.sourceforge.plantuml.tim.Eater; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TLineType; import net.sourceforge.plantuml.tim.TMemory; public class TokenStack { final private List tokens; + public boolean isSpecialAffectationWhenFunctionCall() { + if (tokens.size() != 1) { + return false; + } + final Token single = tokens.get(0); + if (single.getTokenType() != TokenType.PLAIN_TEXT) { + return false; + } + return isSpecialAffectationWhenFunctionCall(single.getSurface()); + } + + public static boolean isSpecialAffectationWhenFunctionCall(String surface) { + final int idx = surface.indexOf('='); + if (idx <= 0) { + return false; + } + if (TLineType.isLetterOrUnderscoreOrDollar(surface.charAt(0)) == false) { + return false; + } + for (int i = 1; i < idx; i++) { + if (TLineType.isLetterOrUnderscoreOrDigit(surface.charAt(i)) == false) { + return false; + } + } + return true; + } + public TokenStack() { this(new ArrayList()); } @@ -208,7 +236,8 @@ public class TokenStack { return new InternalIterator(); } - public TValue getResult(LineLocation location, TContext context, TMemory memory) throws EaterException, EaterExceptionLocated { + public TValue getResult(LineLocation location, TContext context, TMemory memory) + throws EaterException, EaterExceptionLocated { final Knowledge knowledge = context.asKnowledge(memory, location); final TokenStack tmp = withoutSpace(); tmp.guessFunctions(); diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java index c9b3389f4..f91f16bd1 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorAffectation.java @@ -82,7 +82,7 @@ public class CodeIteratorAffectation extends AbstractCodeIterator { return; } catch (ParseException e) { if (e.getColumn() <= lastLocation) { - throw EaterException.located("Error in JSON format", result); + throw EaterException.located("Error in JSON format"); } lastLocation = e.getColumn(); next(); diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java index aae35792a..54ca065bf 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorForeach.java @@ -92,7 +92,7 @@ public class CodeIteratorForeach extends AbstractCodeIterator { } else if (result.getType() == TLineType.ENDFOREACH) { logs.add(result); if (foreach == null) { - throw EaterException.located("No foreach related to this endforeach", result); + throw EaterException.located("No foreach related to this endforeach"); } foreach.inc(); if (foreach.isSkipMe()) { diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java index 51df6d7eb..acaf0cfcc 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java @@ -117,7 +117,7 @@ public class CodeIteratorIf extends AbstractCodeIterator { private void executeElseIf(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated { final ExecutionContextIf poll = (ExecutionContextIf) memory.peekIf(); if (poll == null) { - throw EaterException.located("No if related to this else", s); + throw EaterException.located("No if related to this else"); } poll.enteringElseIf(); @@ -148,7 +148,7 @@ public class CodeIteratorIf extends AbstractCodeIterator { private void executeElse(TContext context, TMemory memory, StringLocated s) throws EaterException { final ExecutionContextIf poll = (ExecutionContextIf) memory.peekIf(); if (poll == null) { - throw EaterException.located("No if related to this else", s); + throw EaterException.located("No if related to this else"); } poll.nowInElse(); } @@ -156,7 +156,7 @@ public class CodeIteratorIf extends AbstractCodeIterator { private void executeEndif(TContext context, TMemory memory, StringLocated s) throws EaterException { final ExecutionContextIf poll = (ExecutionContextIf) memory.pollIf(); if (poll == null) { - throw EaterException.located("No if related to this endif", s); + throw EaterException.located("No if related to this endif"); } } diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java index 7f3656dc0..d3e065a67 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java @@ -80,7 +80,7 @@ public class CodeIteratorSub extends AbstractCodeIterator { StringLocated s = null; while ((s = source.peek()) != null) { if (s.getType() == TLineType.STARTSUB) { - throw EaterException.located("Cannot nest sub", s); + throw EaterException.located("Cannot nest sub"); } else if (s.getType() == TLineType.ENDSUB) { source.next(); readingInProgress = new CodeIteratorImpl(created.lines()); diff --git a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java index 716d36125..4b796bfee 100644 --- a/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java +++ b/src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java @@ -91,7 +91,7 @@ public class CodeIteratorWhile extends AbstractCodeIterator { } else if (result.getType() == TLineType.ENDWHILE) { logs.add(result); if (currentWhile == null) { - throw EaterException.located("No while related to this endwhile", result); + throw EaterException.located("No while related to this endwhile"); } final TValue value = currentWhile.conditionValue(result.getLocation(), context, memory); if (value.toBoolean()) { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java index 2aeb6f656..a62dac908 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,11 +52,12 @@ public class AlwaysFalse extends SimpleReturnFunction { return new TFunctionSignature("%false", 0); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { return TValue.fromBoolean(false); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java index 519d80bfb..76bf7832b 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,11 +52,12 @@ public class AlwaysTrue extends SimpleReturnFunction { return new TFunctionSignature("%true", 0); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { return TValue.fromBoolean(true); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java index 9f80086cc..ce0b16e9c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java @@ -34,7 +34,10 @@ */ package net.sourceforge.plantuml.tim.stdlib; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; @@ -51,11 +54,12 @@ public class CallUserFunction extends SimpleReturnFunction { return new TFunctionSignature("%call_user_func", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg > 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values) throws EaterException, EaterExceptionLocated { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { final String fname = values.get(0).toString(); final List args = values.subList(1, values.size()); final TFunctionSignature signature = new TFunctionSignature(fname, args.size()); @@ -63,7 +67,7 @@ public class CallUserFunction extends SimpleReturnFunction { if (func == null) { throw EaterException.unlocated("Cannot find void function " + fname); } - return func.executeReturnFunction(context, memory, location, args); + return func.executeReturnFunction(context, memory, location, args, Collections.emptyMap()); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java index 29357d4f6..0cfe02881 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java @@ -37,9 +37,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -51,15 +54,16 @@ public class DateFunction extends SimpleReturnFunction { return new TFunctionSignature("%date", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0 || nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - if (args.size() == 0) { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + if (values.size() == 0) { return TValue.fromString(new Date().toString()); } - final String format = args.get(0).toString(); + final String format = values.get(0).toString(); try { return TValue.fromString(new SimpleDateFormat(format).format(new Date())); } catch (Exception e) { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java b/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java index c55c6711e..9d402d3c0 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java @@ -35,10 +35,13 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -56,11 +59,12 @@ public class Dirpath extends SimpleReturnFunction { return new TFunctionSignature("%dirpath", 0); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { if (value == null) { return TValue.fromString(""); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java b/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java index e92bff329..163988051 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java @@ -36,10 +36,13 @@ package net.sourceforge.plantuml.tim.stdlib; import java.io.File; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -51,15 +54,16 @@ public class FileExists extends SimpleReturnFunction { return new TFunctionSignature("%file_exists", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { if (OptionFlags.ALLOW_INCLUDE == false) { return TValue.fromBoolean(false); } - final String path = args.get(0).toString(); + final String path = values.get(0).toString(); return TValue.fromBoolean(fileExists(path)); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Filename.java b/src/net/sourceforge/plantuml/tim/stdlib/Filename.java index 122640169..412fa1c26 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Filename.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Filename.java @@ -35,10 +35,13 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -56,11 +59,12 @@ public class Filename extends SimpleReturnFunction { return new TFunctionSignature("%filename", 0); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { if (value == null) { return TValue.fromString(""); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java b/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java index 01e8b77c5..2c1622964 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +52,12 @@ public class FunctionExists extends SimpleReturnFunction { return new TFunctionSignature("%function_exists", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final String name = args.get(0).toString(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { + final String name = values.get(0).toString(); return TValue.fromBoolean(context.doesFunctionExist(name)); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java index 89d14b938..02df76d76 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +52,13 @@ public class GetVariableValue extends SimpleReturnFunction { return new TFunctionSignature("%get_variable_value", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final String name = args.get(0).toString(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final String name = values.get(0).toString(); final TValue variable = memory.getVariable(name); if (variable == null) { return TValue.fromString(""); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java b/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java index 39e5dcf1c..52437cee5 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -50,11 +53,12 @@ public class GetVersion extends SimpleReturnFunction { return new TFunctionSignature("%version", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { return TValue.fromString(Version.versionString()); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java b/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java index 2787735aa..794929101 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java @@ -35,10 +35,13 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -50,15 +53,16 @@ public class Getenv extends SimpleReturnFunction { return new TFunctionSignature("%getenv", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { if (OptionFlags.ALLOW_INCLUDE == false) { return TValue.fromString(""); } - final String name = args.get(0).toString(); + final String name = values.get(0).toString(); final String value = getenv(name); if (value == null) { return TValue.fromString(""); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java b/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java index 934c9363b..f3ada7986 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java @@ -35,10 +35,13 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -50,12 +53,13 @@ public class IntVal extends SimpleReturnFunction { return new TFunctionSignature("%intval", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final String s = args.get(0).toString(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final String s = values.get(0).toString(); try { return TValue.fromInt(Integer.parseInt(s)); } catch (Exception e) { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java b/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java index d4c4841fb..cb46708db 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java @@ -34,7 +34,10 @@ */ package net.sourceforge.plantuml.tim.stdlib; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringLocated; @@ -54,7 +57,7 @@ public class InvokeProcedure implements TFunction { return new TFunctionSignature("%invoke_procedure", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg > 0; } @@ -62,7 +65,8 @@ public class InvokeProcedure implements TFunction { return TFunctionType.PROCEDURE; } - public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) throws EaterException, EaterExceptionLocated { + public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) + throws EaterException, EaterExceptionLocated { final EaterFunctionCall call = new EaterFunctionCall(new StringLocated(s, location), false, isUnquoted()); call.analyze((TContext) context, memory); final List values = call.getValues(); @@ -71,17 +75,18 @@ public class InvokeProcedure implements TFunction { final TFunctionSignature signature = new TFunctionSignature(fname, args.size()); final TFunction func = context.getFunctionSmart(signature); if (func == null) { - throw EaterException.located("Cannot find void function " + fname, new StringLocated(s, location)); + throw EaterException.located("Cannot find void function " + fname); } - func.executeProcedureInternal(context, memory, args); + func.executeProcedureInternal(context, memory, args, Collections.emptyMap()); } - public void executeProcedureInternal(TContext context, TMemory memory, List args) throws EaterException { + public void executeProcedureInternal(TContext context, TMemory memory, List args, + Map named) { throw new UnsupportedOperationException(); } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) - throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java index 7bed63fa6..82e83fd46 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +52,13 @@ public class LogicalNot extends SimpleReturnFunction { return new TFunctionSignature("%not", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final boolean arg = args.get(0).toBoolean(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final boolean arg = values.get(0).toBoolean(); return TValue.fromBoolean(!arg); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Lower.java b/src/net/sourceforge/plantuml/tim/stdlib/Lower.java index 160f86755..901228fb8 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Lower.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Lower.java @@ -35,9 +35,10 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +50,12 @@ public class Lower extends SimpleReturnFunction { return new TFunctionSignature("%lower", 3); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) - throws EaterException { - return TValue.fromString(args.get(0).toString().toLowerCase()); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) { + return TValue.fromString(values.get(0).toString().toLowerCase()); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java b/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java index 330192222..5ea759c69 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java @@ -34,7 +34,10 @@ */ package net.sourceforge.plantuml.tim.stdlib; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; @@ -51,17 +54,18 @@ public class RetrieveProcedure extends SimpleReturnFunction { return new TFunctionSignature("%retrieve_procedure", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg > 0; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values) throws EaterException, EaterExceptionLocated { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { final String fname = values.get(0).toString(); final List args = values.subList(1, values.size()); final TFunctionSignature signature = new TFunctionSignature(fname, args.size()); final TFunction func = context.getFunctionSmart(signature); final int n1 = context.getResultList().size(); - func.executeProcedureInternal(context, memory, args); + func.executeProcedureInternal(context, memory, args, Collections.emptyMap()); final String extracted = context.extractFromResultList(n1); return TValue.fromString(extracted); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java index 31efb7b40..c40585849 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -50,16 +53,17 @@ public class SetVariableValue extends SimpleReturnFunction { return new TFunctionSignature("%set_variable_value", 2); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { // if (memory instanceof TMemoryLocal) { // memory = ((TMemoryLocal) memory).getGlobalForInternalUseOnly(); // } - final String name = args.get(0).toString(); - final TValue value = args.get(1); + final String name = values.get(0).toString(); + final TValue value = values.get(1); memory.putVariable(name, value, TVariableScope.GLOBAL); return TValue.fromString(""); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java index 8520e865a..22a4a9f90 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java @@ -35,6 +35,7 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; @@ -50,18 +51,18 @@ public abstract class SimpleReturnFunction implements TFunction { return TFunctionType.RETURN_FUNCTION; } - final public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) throws EaterException { + final public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) + throws EaterException { throw new UnsupportedOperationException(); } - final public void executeProcedureInternal(TContext context, TMemory memory, List args) throws EaterException { + final public void executeProcedureInternal(TContext context, TMemory memory, List args, + Map named) throws EaterException { throw new UnsupportedOperationException(); } - + final public boolean isUnquoted() { return false; } - - } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java index 1c2a1ce7a..2db00cea3 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java @@ -35,9 +35,10 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +50,12 @@ public class StringFunction extends SimpleReturnFunction { return new TFunctionSignature("%string", 3); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) - throws EaterException { - return TValue.fromString(args.get(0).toString()); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) { + return TValue.fromString(values.get(0).toString()); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java index 3b0f3bd78..ae132b571 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,11 +52,12 @@ public class Strlen extends SimpleReturnFunction { return new TFunctionSignature("%strlen", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - return TValue.fromInt(args.get(0).toString().length()); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + return TValue.fromInt(values.get(0).toString().length()); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java b/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java index e54090bca..d4a70212c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,13 +52,14 @@ public class Strpos extends SimpleReturnFunction { return new TFunctionSignature("%strpos", 2); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final String full = args.get(0).toString(); - final String searched = args.get(1).toString(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final String full = values.get(0).toString(); + final String searched = values.get(1).toString(); return TValue.fromInt(full.indexOf(searched)); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Substr.java b/src/net/sourceforge/plantuml/tim/stdlib/Substr.java index a3fa9186f..750cd1b1e 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Substr.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Substr.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,19 +52,20 @@ public class Substr extends SimpleReturnFunction { return new TFunctionSignature("%substr", 3); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2 || nbArg == 3; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final String full = args.get(0).toString(); - final int pos = args.get(1).toInt(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final String full = values.get(0).toString(); + final int pos = values.get(1).toInt(); if (pos >= full.length()) { return TValue.fromString(""); } String result = full.substring(pos); - if (args.size() == 3) { - final int len = args.get(2).toInt(); + if (values.size() == 3) { + final int len = values.get(2).toInt(); if (len < result.length()) { result = result.substring(0, len); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Upper.java b/src/net/sourceforge/plantuml/tim/stdlib/Upper.java index 350d6c15a..62b4d225a 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Upper.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Upper.java @@ -35,9 +35,10 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; -import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +50,12 @@ public class Upper extends SimpleReturnFunction { return new TFunctionSignature("%upper", 3); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) - throws EaterException { - return TValue.fromString(args.get(0).toString().toUpperCase()); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) { + return TValue.fromString(values.get(0).toString().toUpperCase()); } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java b/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java index dda324a14..c2c813586 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java @@ -35,9 +35,12 @@ package net.sourceforge.plantuml.tim.stdlib; import java.util.List; +import java.util.Map; +import java.util.Set; import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; import net.sourceforge.plantuml.tim.TContext; import net.sourceforge.plantuml.tim.TFunctionSignature; import net.sourceforge.plantuml.tim.TMemory; @@ -49,12 +52,13 @@ public class VariableExists extends SimpleReturnFunction { return new TFunctionSignature("%variable_exists", 1); } - public boolean canCover(int nbArg) { + public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args) throws EaterException { - final String name = args.get(0).toString(); + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final String name = values.get(0).toString(); return TValue.fromBoolean(memory.getVariable(name) != null); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingNote.java b/src/net/sourceforge/plantuml/timingdiagram/TimingNote.java index 4ab0f04be..c1e8abf0c 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingNote.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingNote.java @@ -40,9 +40,10 @@ import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.command.Position; import net.sourceforge.plantuml.creole.CreoleMode; -import net.sourceforge.plantuml.creole.CreoleParser; +import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.Sheet; import net.sourceforge.plantuml.creole.SheetBlock1; +import net.sourceforge.plantuml.creole.legacy.CreoleParser; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -84,8 +85,8 @@ public class TimingNote { final HColor noteBackgroundColor = rose.getHtmlColor(skinParam, ColorParam.noteBackground); final HColor borderColor = rose.getHtmlColor(skinParam, ColorParam.noteBorder); - final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, - CreoleMode.FULL).createSheet(note); + final Sheet sheet = Parser.build(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL) + .createSheet(note); final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()); final double shadowing; shadowing = skinParam.shadowing(null) ? 4 : 0; diff --git a/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java b/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java index d02a18424..a93937116 100644 --- a/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java +++ b/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.ugraphic; +import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.ColorMapperTransparentWrapper; import net.sourceforge.plantuml.ugraphic.color.HColor; @@ -160,8 +161,19 @@ public abstract class AbstractCommonUGraphic implements UGraphic { return new ColorMapperTransparentWrapper(colorMapper); } - public void flushUg() { + final public void flushUg() { + } + public void startUrl(Url url) { + } + + public void closeUrl() { + } + + public void startGroup(String groupId) { + } + + public void closeGroup() { } public boolean matchesProperty(String propertyName) { diff --git a/src/net/sourceforge/plantuml/ugraphic/LimitFinder.java b/src/net/sourceforge/plantuml/ugraphic/LimitFinder.java index 1da462ed3..997891cf1 100644 --- a/src/net/sourceforge/plantuml/ugraphic/LimitFinder.java +++ b/src/net/sourceforge/plantuml/ugraphic/LimitFinder.java @@ -47,7 +47,7 @@ import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.color.HColor; -public class LimitFinder implements UGraphic { +public class LimitFinder extends UGraphicNo implements UGraphic { public boolean matchesProperty(String propertyName) { return false; @@ -219,12 +219,6 @@ public class LimitFinder implements UGraphic { return new ColorMapperIdentity(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public double getMaxX() { return minmax.getMaxX(); } diff --git a/src/net/sourceforge/plantuml/ugraphic/TextLimitFinder.java b/src/net/sourceforge/plantuml/ugraphic/TextLimitFinder.java index 05869e0ce..3f9918090 100644 --- a/src/net/sourceforge/plantuml/ugraphic/TextLimitFinder.java +++ b/src/net/sourceforge/plantuml/ugraphic/TextLimitFinder.java @@ -37,22 +37,20 @@ package net.sourceforge.plantuml.ugraphic; import java.awt.geom.Dimension2D; -import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.HColor; -public class TextLimitFinder implements UGraphic { +public class TextLimitFinder extends UGraphicNo implements UGraphic { public boolean matchesProperty(String propertyName) { return false; } - + public double dpiFactor() { return 1; } - public UGraphic apply(UChange change) { if (change instanceof UTranslate) { return new TextLimitFinder(stringBounder, minmax, translate.compose((UTranslate) change)); @@ -104,12 +102,6 @@ public class TextLimitFinder implements UGraphic { throw new UnsupportedOperationException(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - private void drawText(double x, double y, UText text) { final Dimension2D dim = stringBounder.calculateDimension(text.getFontConfiguration().getFont(), text.getText()); y -= dim.getHeight() - 1.5; diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphic.java b/src/net/sourceforge/plantuml/ugraphic/UGraphic.java index 450da3947..fb947192f 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UGraphic.java +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphic.java @@ -53,10 +53,14 @@ public interface UGraphic { public void startUrl(Url url); - public void closeAction(); + public void closeUrl(); + + public void startGroup(String id); + + public void closeGroup(); public void flushUg(); public boolean matchesProperty(String propertyName); - + } diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicNo.java b/src/net/sourceforge/plantuml/ugraphic/UGraphicNo.java new file mode 100644 index 000000000..93480f23d --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphicNo.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.ugraphic; + +import net.sourceforge.plantuml.Url; + +public abstract class UGraphicNo { + + final public void startUrl(Url url) { + } + + final public void startGroup(String groupId) { + } + + final public void closeUrl() { + } + + final public void closeGroup() { + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicNull.java b/src/net/sourceforge/plantuml/ugraphic/UGraphicNull.java index 2b95abec9..ffa4f25f8 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UGraphicNull.java +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphicNull.java @@ -64,12 +64,6 @@ public class UGraphicNull extends AbstractUGraphic implements EnsureVisi return FileFormat.PNG.getDefaultStringBounder(TikzFontDistortion.getDefault()); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public void writeImageTOBEMOVED(OutputStream os, String metadata, int dpi) throws IOException { } diff --git a/src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java b/src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java index 02539b58c..44370dca1 100644 --- a/src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java +++ b/src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java @@ -35,14 +35,14 @@ */ package net.sourceforge.plantuml.ugraphic.comp; -import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.TextLimitFinder; -import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UBackground; +import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UEmpty; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicNo; import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UParamNull; import net.sourceforge.plantuml.ugraphic.UPath; @@ -57,7 +57,7 @@ import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.color.HColor; -public class SlotFinder implements UGraphic { +public class SlotFinder extends UGraphicNo implements UGraphic { public boolean matchesProperty(String propertyName) { return false; @@ -194,12 +194,6 @@ public class SlotFinder implements UGraphic { return new ColorMapperIdentity(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public SlotSet getSlotSet() { return slot; } diff --git a/src/net/sourceforge/plantuml/ugraphic/crossing/UGraphicCrossing.java b/src/net/sourceforge/plantuml/ugraphic/crossing/UGraphicCrossing.java index 6dca67fb7..d466331e6 100644 --- a/src/net/sourceforge/plantuml/ugraphic/crossing/UGraphicCrossing.java +++ b/src/net/sourceforge/plantuml/ugraphic/crossing/UGraphicCrossing.java @@ -38,27 +38,23 @@ import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.cute.Balloon; import net.sourceforge.plantuml.cute.CrossingSegment; import net.sourceforge.plantuml.geom.LineSegmentDouble; -import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.UGraphicDelegator; import net.sourceforge.plantuml.posimo.DotPath; import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UShape; import net.sourceforge.plantuml.ugraphic.UTranslate; -import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorUtils; -public class UGraphicCrossing implements UGraphic { +public class UGraphicCrossing extends UGraphicDelegator implements UGraphic { - private final UGraphic ug; private final List lines; private final UTranslate translate; - + static class Pending { final UGraphic ug; final LineSegmentDouble segment; @@ -104,57 +100,37 @@ public class UGraphicCrossing implements UGraphic { } private UGraphicCrossing(UGraphic ug, UTranslate translate, List lines) { - this.ug = ug; + super(ug); this.translate = translate; this.lines = lines; } - public StringBounder getStringBounder() { - return ug.getStringBounder(); - } - - public UParam getParam() { - return ug.getParam(); - } - public void draw(UShape shape) { if (shape instanceof DotPath) { drawDotPath((DotPath) shape); } else { - ug.draw(shape); + getUg().draw(shape); } } private void drawDotPath(DotPath dotPath) { if (dotPath.isLine()) { for (LineSegmentDouble seg : dotPath.getLineSegments()) { - lines.add(new Pending(ug.apply(translate.reverse()), translate, seg.translate(translate))); + lines.add(new Pending(getUg().apply(translate.reverse()), translate, seg.translate(translate))); } } else { - ug.draw(dotPath); + getUg().draw(dotPath); } } public UGraphic apply(UChange change) { if (change instanceof UTranslate) { - return new UGraphicCrossing(ug.apply(change), translate.compose((UTranslate) change), lines); + return new UGraphicCrossing(getUg().apply(change), translate.compose((UTranslate) change), lines); } else { - return new UGraphicCrossing(ug.apply(change), translate, lines); + return new UGraphicCrossing(getUg().apply(change), translate, lines); } } - public ColorMapper getColorMapper() { - return ug.getColorMapper(); - } - - public void startUrl(Url url) { - ug.startUrl(url); - } - - public void closeAction() { - ug.closeAction(); - } - public void flushUg() { final List pendings = new ArrayList(); final List balloons = new ArrayList(); @@ -170,22 +146,18 @@ public class UGraphicCrossing implements UGraphic { // } } for (Balloon b : balloons) { - b.drawU(ug.apply(HColorUtils.GREEN.bg()).apply(HColorUtils.GREEN)); + b.drawU(getUg().apply(HColorUtils.GREEN.bg()).apply(HColorUtils.GREEN)); } for (Pending p : lines) { for (Balloon b : balloons) { List pts = new CrossingSegment(b, p.segment).intersection(); for (Point2D pt : pts) { final Balloon s2 = new Balloon(pt, 2); - s2.drawU(ug.apply(HColorUtils.BLUE.bg()).apply(HColorUtils.BLUE)); + s2.drawU(getUg().apply(HColorUtils.BLUE.bg()).apply(HColorUtils.BLUE)); } } } - ug.flushUg(); - } - - public boolean matchesProperty(String propertyName) { - return ug.matchesProperty(propertyName); + getUg().flushUg(); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java index 669ae5796..1c517bd95 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java @@ -131,7 +131,7 @@ public class UGraphicEps extends AbstractUGraphic implements ClipCo getGraphicObject().openLink(url.getUrl()); } - public void closeAction() { + public void closeUrl() { getGraphicObject().closeLink(); } diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java index fa0eca60d..d6c9065cc 100644 --- a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java @@ -193,7 +193,7 @@ public class UGraphicG2d extends AbstractUGraphic implements EnsureV allUrls.add(url); } - public void closeAction() { + public void closeUrl() { urls.remove(urls.size() - 1); } diff --git a/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java b/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java index c9cdf0bf8..d934f8f16 100644 --- a/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java +++ b/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java @@ -36,41 +36,29 @@ package net.sourceforge.plantuml.ugraphic.hand; import java.util.Random; -import net.sourceforge.plantuml.Url; -import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.UGraphicDelegator; import net.sourceforge.plantuml.posimo.DotPath; import net.sourceforge.plantuml.ugraphic.UChange; import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; -import net.sourceforge.plantuml.ugraphic.UParam; import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.UPolygon; import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UShape; -import net.sourceforge.plantuml.ugraphic.color.ColorMapper; import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; -public class UGraphicHandwritten implements UGraphic { +public class UGraphicHandwritten extends UGraphicDelegator implements UGraphic { - private final UGraphic ug; private final Random rnd = new Random(424242L); public UGraphicHandwritten(UGraphic ug) { - this.ug = ug; + super(ug); if (ug instanceof UGraphicSvg) { ((UGraphicSvg) ug).enlargeClip(); } } - public StringBounder getStringBounder() { - return ug.getStringBounder(); - } - - public UParam getParam() { - return ug.getParam(); - } - public void draw(UShape shape) { // http://www.ufonts.com/fonts/felt-tip-roman.html // http://webdesignledger.com/freebies/20-amazing-free-handwritten-fonts-for-your-designs @@ -87,62 +75,42 @@ public class UGraphicHandwritten implements UGraphic { } else if (shape instanceof UPath) { drawHand((UPath) shape); } else { - ug.draw(shape); + getUg().draw(shape); } } private void drawHand(UPath shape) { final UPathHand uline = new UPathHand(shape, rnd); - ug.draw(uline.getHanddrawn()); + getUg().draw(uline.getHanddrawn()); } private void drawHand(DotPath shape) { final UDotPathHand uline = new UDotPathHand(shape, rnd); - ug.draw(uline.getHanddrawn()); + getUg().draw(uline.getHanddrawn()); } private void drawHand(UPolygon shape) { final UPolygonHand hand = new UPolygonHand(shape, rnd); - ug.draw(hand.getHanddrawn()); + getUg().draw(hand.getHanddrawn()); } private void drawHand(URectangle shape) { final URectangleHand hand = new URectangleHand(shape, rnd); - ug.draw(hand.getHanddrawn()); + getUg().draw(hand.getHanddrawn()); } private void drawHand(ULine shape) { final ULineHand uline = new ULineHand(shape, rnd); - ug.draw(uline.getHanddrawn()); + getUg().draw(uline.getHanddrawn()); } private void drawHand(UEllipse shape) { final UEllipseHand uline = new UEllipseHand(shape, rnd); - ug.draw(uline.getHanddrawn()); + getUg().draw(uline.getHanddrawn()); } public UGraphic apply(UChange change) { - return new UGraphicHandwritten(ug.apply(change)); - } - - public ColorMapper getColorMapper() { - return ug.getColorMapper(); - } - - public void startUrl(Url url) { - ug.startUrl(url); - } - - public void closeAction() { - ug.closeAction(); - } - - public void flushUg() { - ug.flushUg(); - } - - public boolean matchesProperty(String propertyName) { - return ug.matchesProperty(propertyName); + return new UGraphicHandwritten(getUg().apply(change)); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/html5/UGraphicHtml5.java b/src/net/sourceforge/plantuml/ugraphic/html5/UGraphicHtml5.java index 954ded16c..d5061db2f 100644 --- a/src/net/sourceforge/plantuml/ugraphic/html5/UGraphicHtml5.java +++ b/src/net/sourceforge/plantuml/ugraphic/html5/UGraphicHtml5.java @@ -79,16 +79,6 @@ public class UGraphicHtml5 extends AbstractUGraphic implements Clip return stringBounder; } - public void startUrl(Url url) { - // throw new UnsupportedOperationException(); - - } - - public void closeAction() { - // throw new UnsupportedOperationException(); - - } - // public void close() { // getEpsGraphics().close(); // } diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java index 51231eafa..e3b042088 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -89,8 +89,9 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio) { - this(minDim, colorMapper, new SvgGraphics(svgDimensionStyle, minDim, backcolor, scale, hover, seed, - preserveAspectRatio), textAsPath, linkTarget); + this(minDim, colorMapper, + new SvgGraphics(svgDimensionStyle, minDim, backcolor, scale, hover, seed, preserveAspectRatio), + textAsPath, linkTarget); } public UGraphicSvg(boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, boolean textAsPath, @@ -168,11 +169,25 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo } } + @Override + public void startGroup(String groupId) { + getGraphicObject().startGroup(groupId); + + } + + @Override + public void closeGroup() { + getGraphicObject().closeGroup(); + } + + + @Override public void startUrl(Url url) { getGraphicObject().openLink(url.getUrl(), url.getTooltip(), target); } - public void closeAction() { + @Override + public void closeUrl() { getGraphicObject().closeLink(); } diff --git a/src/net/sourceforge/plantuml/ugraphic/tikz/DriverAtomTextTikz.java b/src/net/sourceforge/plantuml/ugraphic/tikz/DriverAtomTextTikz.java index a34817ee5..d675aecb9 100644 --- a/src/net/sourceforge/plantuml/ugraphic/tikz/DriverAtomTextTikz.java +++ b/src/net/sourceforge/plantuml/ugraphic/tikz/DriverAtomTextTikz.java @@ -34,7 +34,7 @@ */ package net.sourceforge.plantuml.ugraphic.tikz; -import net.sourceforge.plantuml.creole.atom.AtomText; +import net.sourceforge.plantuml.creole.legacy.AtomText; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontStyle; import net.sourceforge.plantuml.tikz.TikzGraphics; diff --git a/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java b/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java index ddf12f054..70c6c4660 100644 --- a/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java +++ b/src/net/sourceforge/plantuml/ugraphic/tikz/UGraphicTikz.java @@ -40,7 +40,7 @@ import java.io.OutputStream; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.TikzFontDistortion; import net.sourceforge.plantuml.Url; -import net.sourceforge.plantuml.creole.atom.AtomText; +import net.sourceforge.plantuml.creole.legacy.AtomText; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.posimo.DotPath; import net.sourceforge.plantuml.tikz.TikzGraphics; @@ -113,7 +113,7 @@ public class UGraphicTikz extends AbstractUGraphic implements Clip getGraphicObject().openLink(url.getUrl(), url.getTooltip()); } - public void closeAction() { + public void closeUrl() { getGraphicObject().closeLink(); } diff --git a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java index 97944ffa9..571497d7a 100644 --- a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java +++ b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java @@ -109,12 +109,6 @@ public class UGraphicTxt extends AbstractCommonUGraphic implements ClipContainer return (int) getTranslateX(); } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public Dimension2D getDimension() { return new Dimension2DDouble(0, 0); } diff --git a/src/net/sourceforge/plantuml/ugraphic/visio/UGraphicVdx.java b/src/net/sourceforge/plantuml/ugraphic/visio/UGraphicVdx.java index 19288d29e..dda7b279d 100644 --- a/src/net/sourceforge/plantuml/ugraphic/visio/UGraphicVdx.java +++ b/src/net/sourceforge/plantuml/ugraphic/visio/UGraphicVdx.java @@ -40,7 +40,7 @@ import java.io.OutputStream; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.TikzFontDistortion; import net.sourceforge.plantuml.Url; -import net.sourceforge.plantuml.creole.atom.AtomText; +import net.sourceforge.plantuml.creole.legacy.AtomText; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.posimo.DotPath; import net.sourceforge.plantuml.ugraphic.AbstractCommonUGraphic; @@ -107,12 +107,6 @@ public class UGraphicVdx extends AbstractUGraphic implements Clip return stringBounder; } - public void startUrl(Url url) { - } - - public void closeAction() { - } - public void writeImageTOBEMOVED(OutputStream os, String metadata, int dpi) throws IOException { createVsd(os); } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index d5ff888c4..87f7c60a4 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 1202009; + return 1202010; } public static int versionPatched() { @@ -92,7 +92,7 @@ public class Version { } public static long compileTime() { - return 1589107866768L; + return 1589708157515L; } public static String compileTimeString() {