diff --git a/pom.xml b/pom.xml index b1c6b72ae..1a0292ecc 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ net.sourceforge.plantuml plantuml - 1.2021.8-SNAPSHOT + 1.2021.9-SNAPSHOT jar PlantUML @@ -227,11 +227,6 @@ forked-path - - org.codehaus.mojo - versions-maven-plugin - 2.8.1 - diff --git a/skin/plantuml.skin b/skin/plantuml.skin index 55b28739f..0826d7186 100644 --- a/skin/plantuml.skin +++ b/skin/plantuml.skin @@ -289,6 +289,7 @@ ganttDiagram { } timeline { BackgroundColor transparent + LineColor #C0C0C0 } closed { BackGroundColor #E0E8E8 diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index 81cc81a00..0ec06098b 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -78,7 +78,7 @@ public interface ISkinParam extends ISkinSimple { public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam); public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection, - boolean isReverseDefine); + boolean isReverseDefine, HorizontalAlignment overrideDefault); public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue); diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java index 610b69ac1..4caeb0700 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -72,6 +72,7 @@ public class Option { private OptionPreprocOutputMode preprocessorOutput = null; private boolean failfast = false; private boolean failfast2 = false; + private boolean noerror = false; private boolean duration = false; private boolean debugsvek = false; @@ -228,6 +229,8 @@ public class Option { this.failfast = true; } else if (s.equalsIgnoreCase("-failfast2")) { this.failfast2 = true; + } else if (s.equalsIgnoreCase("-noerror")) { + this.noerror = true; } else if (s.equalsIgnoreCase("-checkonly")) { this.checkOnly = true; } else if (s.equalsIgnoreCase("-theme")) { @@ -619,6 +622,14 @@ public class Option { this.failfast2 = failfast2; } + public final void setNoerror(boolean noerror) { + this.noerror = noerror; + } + + public final boolean isNoerror() { + return noerror; + } + public final File getOutputFile() { return outputFile; } diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java index 9fe2e05fa..e45fe88a7 100644 --- a/src/net/sourceforge/plantuml/OptionPrint.java +++ b/src/net/sourceforge/plantuml/OptionPrint.java @@ -108,7 +108,7 @@ public class OptionPrint { + "file\tTo include file as if '!include file' were used"); System.out.println( " -I" + separator + "path" + separator + "to" + separator + "*.puml\tTo include files with pattern"); - System.out.println(" -theme xxx\\t\\tTo use a specific theme"); + System.out.println(" -theme xxx\t\tTo use a specific theme"); System.out.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")"); System.out.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern"); System.out.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images"); @@ -133,6 +133,7 @@ public class OptionPrint { System.out.println(" -checkonly\t\tTo check the syntax of files without generating images"); System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs"); System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster"); + System.out.println(" -noerror\t\tTo skip images when error in diagrams"); System.out.println(" -duration\t\tTo print the duration of complete diagrams processing"); System.out.println(" -nbthread N\t\tTo use (N) threads for processing"); System.out.println(" -nbthread auto\tTo use " + Option.defaultNbThreads() + " threads for processing"); diff --git a/src/net/sourceforge/plantuml/Run.java b/src/net/sourceforge/plantuml/Run.java index 0c638515e..4eb53b8af 100644 --- a/src/net/sourceforge/plantuml/Run.java +++ b/src/net/sourceforge/plantuml/Run.java @@ -493,6 +493,7 @@ public class Run { option.getConfig(), option.getCharset(), option.getFileFormatOption()); } sourceFileReader.setCheckMetadata(option.isCheckMetadata()); + ((SourceFileReaderAbstract) sourceFileReader).setNoerror(option.isNoerror()); if (option.isComputeurl()) { error.goOk(); diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 846465a79..145261956 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -357,7 +357,8 @@ public class SkinParam implements ISkinParam { } public char getCircledCharacter(Stereotype stereotype) { - final String value2 = getValue("spotchar" + Objects.requireNonNull(stereotype).getLabel(Guillemet.DOUBLE_COMPARATOR)); + final String value2 = getValue( + "spotchar" + Objects.requireNonNull(stereotype).getLabel(Guillemet.DOUBLE_COMPARATOR)); if (value2 != null && value2.length() > 0) { return value2.charAt(0); } @@ -613,7 +614,7 @@ public class SkinParam implements ISkinParam { } public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection, - boolean isReverseDefine) { + boolean isReverseDefine, HorizontalAlignment overrideDefault) { final String value; switch (param) { case sequenceMessageAlignment: @@ -662,7 +663,7 @@ public class SkinParam implements ISkinParam { } final HorizontalAlignment result = HorizontalAlignment.fromString(value); if (result == null && param == AlignmentParam.noteTextAlignment) { - return getDefaultTextAlignment(HorizontalAlignment.LEFT); + return getDefaultTextAlignment(overrideDefault == null ? HorizontalAlignment.LEFT : overrideDefault); } else if (result == null && param == AlignmentParam.stateMessageAlignment) { return getDefaultTextAlignment(HorizontalAlignment.CENTER); } else if (result == null) { diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java index 934ba31b7..1d465c86f 100644 --- a/src/net/sourceforge/plantuml/SkinParamDelegator.java +++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java @@ -69,319 +69,398 @@ public class SkinParamDelegator implements ISkinParam { this.skinParam = skinParam; } + @Override public HColor getHyperlinkColor() { return skinParam.getHyperlinkColor(); } + @Override public HColor getBackgroundColor(boolean replaceTransparentByWhite) { return skinParam.getBackgroundColor(replaceTransparentByWhite); } + @Override public int getCircledCharacterRadius() { return skinParam.getCircledCharacterRadius(); } + @Override public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam) { return skinParam.getFont(stereotype, false, fontParam); } + @Override public HColor getFontHtmlColor(Stereotype stereotype, FontParam... param) { return skinParam.getFontHtmlColor(stereotype, param); } + @Override public HColor getHtmlColor(ColorParam param, Stereotype stereotype, boolean clickable) { return skinParam.getHtmlColor(param, stereotype, clickable); } + @Override public String getValue(String key) { return skinParam.getValue(key); } + @Override public int classAttributeIconSize() { return skinParam.classAttributeIconSize(); } + @Override public int getDpi() { return skinParam.getDpi(); } + @Override public DotSplines getDotSplines() { return skinParam.getDotSplines(); } + @Override public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection, - boolean isReverseDefine) { - return skinParam.getHorizontalAlignment(param, arrowDirection, isReverseDefine); + boolean isReverseDefine, HorizontalAlignment overrideDefault) { + return skinParam.getHorizontalAlignment(param, arrowDirection, isReverseDefine, overrideDefault); } + @Override public ColorMapper getColorMapper() { return skinParam.getColorMapper(); } + @Override public boolean shadowing(Stereotype stereotype) { return skinParam.shadowing(stereotype); } + @Override public boolean shadowing2(Stereotype stereotype, SkinParameter skinParameter) { return skinParam.shadowing2(stereotype, skinParameter); } + @Override public PackageStyle packageStyle() { return skinParam.packageStyle(); } + @Override public Sprite getSprite(String name) { return skinParam.getSprite(name); } + @Override public ComponentStyle componentStyle() { return skinParam.componentStyle(); } + @Override public boolean stereotypePositionTop() { return skinParam.stereotypePositionTop(); } + @Override public boolean useSwimlanes(UmlDiagramType type) { return skinParam.useSwimlanes(type); } + @Override public double getNodesep() { return skinParam.getNodesep(); } + @Override public double getRanksep() { return skinParam.getRanksep(); } + @Override public double getRoundCorner(CornerParam param, Stereotype stereotype) { return skinParam.getRoundCorner(param, stereotype); } + @Override public double getDiagonalCorner(CornerParam param, Stereotype stereotype) { return skinParam.getDiagonalCorner(param, stereotype); } + @Override public UStroke getThickness(LineParam param, Stereotype stereotype) { return skinParam.getThickness(param, stereotype); } + @Override public LineBreakStrategy maxMessageSize() { return skinParam.maxMessageSize(); } + @Override public LineBreakStrategy wrapWidth() { return skinParam.wrapWidth(); } + @Override public boolean strictUmlStyle() { return skinParam.strictUmlStyle(); } + @Override public boolean forceSequenceParticipantUnderlined() { return skinParam.forceSequenceParticipantUnderlined(); } + @Override public ConditionStyle getConditionStyle() { return skinParam.getConditionStyle(); } + @Override public ConditionEndStyle getConditionEndStyle() { return skinParam.getConditionEndStyle(); } + @Override public double minClassWidth() { return skinParam.minClassWidth(); } + @Override public boolean sameClassWidth() { return skinParam.sameClassWidth(); } + @Override public Rankdir getRankdir() { return skinParam.getRankdir(); } + @Override public boolean useOctagonForActivity(Stereotype stereotype) { return skinParam.useOctagonForActivity(stereotype); } + @Override public HColorSet getIHtmlColorSet() { return skinParam.getIHtmlColorSet(); } + @Override public boolean useUnderlineForHyperlink() { return skinParam.useUnderlineForHyperlink(); } + @Override public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue) { return skinParam.getDefaultTextAlignment(defaultValue); } + @Override public double getPadding() { return skinParam.getPadding(); } + @Override public int groupInheritance() { return skinParam.groupInheritance(); } + @Override public Guillemet guillemet() { return skinParam.guillemet(); } + @Override public boolean handwritten() { return skinParam.handwritten(); } + @Override public String getSvgLinkTarget() { return skinParam.getSvgLinkTarget(); } + @Override public String getPreserveAspectRatio() { return skinParam.getPreserveAspectRatio(); } + @Override public String getMonospacedFamily() { return skinParam.getMonospacedFamily(); } + @Override public Colors getColors(ColorParam param, Stereotype stereotype) throws NoSuchColorException { return skinParam.getColors(param, stereotype); } + @Override public int getTabSize() { return skinParam.getTabSize(); } + @Override public boolean shadowingForNote(Stereotype stereotype) { return shadowingForNote(stereotype); } + @Override public int maxAsciiMessageLength() { return skinParam.maxAsciiMessageLength(); } + @Override public int colorArrowSeparationSpace() { return skinParam.colorArrowSeparationSpace(); } + @Override public SplitParam getSplitParam() { return skinParam.getSplitParam(); } + @Override public int swimlaneWidth() { return skinParam.swimlaneWidth(); } + @Override public UmlDiagramType getUmlDiagramType() { return skinParam.getUmlDiagramType(); } + @Override public HColor hoverPathColor() { return skinParam.hoverPathColor(); } + @Override public double getPadding(PaddingParam param) { return skinParam.getPadding(param); } + @Override public boolean useRankSame() { return skinParam.useRankSame(); } + @Override public boolean displayGenericWithOldFashion() { return skinParam.displayGenericWithOldFashion(); } + @Override public TikzFontDistortion getTikzFontDistortion() { return skinParam.getTikzFontDistortion(); } + @Override public boolean responseMessageBelowArrow() { return skinParam.responseMessageBelowArrow(); } + @Override public boolean svgDimensionStyle() { return skinParam.svgDimensionStyle(); } + @Override public char getCircledCharacter(Stereotype stereotype) { return skinParam.getCircledCharacter(stereotype); } + @Override public LineBreakStrategy swimlaneWrapTitleWidth() { return skinParam.swimlaneWrapTitleWidth(); } + @Override public boolean fixCircleLabelOverlapping() { return skinParam.fixCircleLabelOverlapping(); } + @Override public void setUseVizJs(boolean useVizJs) { skinParam.setUseVizJs(useVizJs); } + @Override public boolean isUseVizJs() { return skinParam.isUseVizJs(); } + @Override public void copyAllFrom(ISkinSimple other) { skinParam.copyAllFrom(other); } + @Override public Map values() { return skinParam.values(); } + @Override public HorizontalAlignment getStereotypeAlignment() { return skinParam.getStereotypeAlignment(); } + @Override public Padder sequenceDiagramPadder() { return skinParam.sequenceDiagramPadder(); } + @Override public StyleBuilder getCurrentStyleBuilder() { return skinParam.getCurrentStyleBuilder(); } + @Override public void muteStyle(Style modifiedStyle) { skinParam.muteStyle(modifiedStyle); } + @Override public Collection getAllSpriteNames() { return skinParam.getAllSpriteNames(); } + @Override public String getDefaultSkin() { return skinParam.getDefaultSkin(); } + @Override public void setDefaultSkin(String newFileName) { skinParam.setDefaultSkin(newFileName); } + @Override public ActorStyle actorStyle() { return skinParam.actorStyle(); } + @Override public void setSvgSize(String origin, String sizeToUse) { skinParam.setSvgSize(origin, sizeToUse); } + @Override public String transformStringForSizeHack(String s) { return skinParam.transformStringForSizeHack(s); } + @Override public LengthAdjust getlengthAdjust() { return skinParam.getlengthAdjust(); } + @Override public void assumeTransparent(ThemeStyle style) { skinParam.assumeTransparent(style); } + @Override public ThemeStyle getThemeStyle() { return skinParam.getThemeStyle(); } diff --git a/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java b/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java index 6e06d3240..86f7074e0 100644 --- a/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java +++ b/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java @@ -50,13 +50,14 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.error.PSystemError; import net.sourceforge.plantuml.preproc.FileWithSuffix; import net.sourceforge.plantuml.security.SFile; import net.sourceforge.plantuml.security.SecurityUtils; -public abstract class SourceFileReaderAbstract { +public abstract class SourceFileReaderAbstract implements ISourceFileReader { protected File file; protected File outputDirectory; @@ -65,6 +66,7 @@ public abstract class SourceFileReaderAbstract { protected BlockUmlBuilder builder; protected FileFormatOption fileFormatOption; private boolean checkMetadata; + private boolean noerror; public void setCheckMetadata(boolean checkMetadata) { this.checkMetadata = checkMetadata; @@ -120,8 +122,8 @@ public abstract class SourceFileReaderAbstract { return Collections.singletonList(image); } - protected void exportWarnOrErrIfWord(final SFile f, final Diagram system) throws FileNotFoundException { - if (OptionFlags.getInstance().isWord()) { + protected void exportWarnOrErrIfWord(SFile f, Diagram system) throws FileNotFoundException { + if (OptionFlags.getInstance().isWord() && f != null) { final String warnOrError = system.getWarningOrError(); if (warnOrError != null) { final String name = f.getName().substring(0, f.getName().length() - 4) + ".err"; @@ -149,6 +151,9 @@ public abstract class SourceFileReaderAbstract { system = blockUml.getDiagram(); } catch (Throwable t) { t.printStackTrace(); + if (OptionFlags.getInstance().isSilentlyCompletelyIgnoreErrors()) { + continue; + } return getCrashedImage(blockUml, t, suggested.getFile(0)); } @@ -157,8 +162,14 @@ public abstract class SourceFileReaderAbstract { } OptionFlags.getInstance().logData(SFile.fromFile(file), system); - final List exportDiagrams = PSystemUtils.exportDiagrams(system, suggested, fileFormatOption, - checkMetadata); + final List exportDiagrams; + if (noerror) { + exportDiagrams = new ArrayList(); + exportDiagrams.add( + new FileImageData(null, new ImageDataSimple(new Dimension2DDouble(0, 0), FileImageData.ERROR))); + } else + exportDiagrams = PSystemUtils.exportDiagrams(system, suggested, fileFormatOption, checkMetadata); + if (exportDiagrams.size() > 1) { cpt += exportDiagrams.size() - 1; } @@ -180,4 +191,9 @@ public abstract class SourceFileReaderAbstract { abstract protected SuggestedFile getSuggestedFile(BlockUml blockUml) throws FileNotFoundException; + protected final void setNoerror(boolean noerror) { + this.noerror = noerror; + + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java index 8a39eb69d..d841bdc65 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java @@ -47,6 +47,9 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory; import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane; import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.color.Colors; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.NoteType; import net.sourceforge.plantuml.ugraphic.color.HColor; public class InstructionSwitch extends WithNote implements Instruction, InstructionCollection { @@ -105,7 +108,7 @@ public class InstructionSwitch extends WithNote implements Instruction, Instruct } final public boolean kill() { - throw new UnsupportedOperationException(); + return current.kill(); } public LinkRendering getInLinkRendering() { @@ -151,6 +154,16 @@ public class InstructionSwitch extends WithNote implements Instruction, Instruct // TODO Auto-generated method stub } + + @Override + public boolean addNote(Display note, NotePosition position, NoteType type, Colors colors, Swimlane swimlaneNote) { + if (current.isEmpty()) { + return super.addNote(note, position, type, colors, swimlaneNote); + } else { + return current.addNote(note, position, type, colors, swimlaneNote); + } + } + // public void afterEndwhile(LinkRendering linkRenderer) { // this.afterEndwhile = linkRenderer; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/AbstractFtile.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/AbstractFtile.java index 69cadd9fb..ab580b315 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/AbstractFtile.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/AbstractFtile.java @@ -103,7 +103,7 @@ public abstract class AbstractFtile extends AbstractTextBlock implements Ftile { } public HorizontalAlignment arrowHorizontalAlignment() { - return skinParam.getHorizontalAlignment(AlignmentParam.arrowMessageAlignment, null, false); + return skinParam.getHorizontalAlignment(AlignmentParam.arrowMessageAlignment, null, false, null); } private FtileGeometry cachedGeometry; diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java index a116a28ed..66580a104 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorSwitch.java @@ -40,6 +40,7 @@ import java.util.List; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.UseStyle; import net.sourceforge.plantuml.activitydiagram3.Branch; import net.sourceforge.plantuml.activitydiagram3.LinkRendering; import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile; @@ -58,6 +59,7 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.Rainbow; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.color.HColor; public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator { @@ -100,7 +102,13 @@ public class FtileFactoryDelegatorSwitch extends FtileFactoryDelegator { for (Branch branch : branches) { ftiles.add(new FtileMinWidthCentered(branch.getFtile(), 30)); } - final Rainbow arrowColor = Rainbow.build(skinParam()); + final Rainbow arrowColor; + if (UseStyle.useBetaStyle()) { + final Style style = getDefaultStyleDefinitionArrow().getMergedStyle(skinParam().getCurrentStyleBuilder()); + arrowColor = Rainbow.build(style, skinParam().getIHtmlColorSet(), skinParam().getThemeStyle()); + } else { + arrowColor = Rainbow.build(skinParam()); + } if (ftiles.size() == 1) { final FtileSwitchWithOneLink result = new FtileSwitchWithOneLink(ftiles, branches, swimlane, diamond1, diamond2, getStringBounder(), arrowColor); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java index d2eb2c015..59cae05cb 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java @@ -230,7 +230,7 @@ public class FtileGroup extends AbstractFtile { .withStroke(stroke).withCorner(roundCorner, 0); final HorizontalAlignment align = inner.skinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, - null, false); + null, false, null); type.asBig(name, align, TextBlockUtils.empty(0, 0), dimTotal.getWidth(), dimTotal.getHeight(), symbolContext, skinParam().getStereotypeAlignment()).drawU(ug); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java index 9b4dd14ee..5939a05b5 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWithNoteOpale.java @@ -163,7 +163,7 @@ public class FtileWithNoteOpale extends AbstractFtile implements Stencil, Stylea } final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, - false); + false, null); final Sheet sheet = Parser.build(fc, align, skinParam, CreoleMode.FULL).createSheet(note.getDisplay()); final TextBlock text = new SheetBlock2(new SheetBlock1(sheet, wrapWidth, skinParam.getPadding()), this, new UStroke(1)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java index e0e9c31e6..9ed739b6d 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/cond/FtileSwitchWithManyLinks.java @@ -126,14 +126,29 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds { return; } final Point2D p1 = getP1(stringBounder); - final Point2D p2 = getP2(stringBounder); - final double x1 = p1.getX(); final double y1 = p1.getY(); + + final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder); + final Point2D ptA = getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointA()); + final Point2D ptB = getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointB()); + final Point2D ptD = getTranslateDiamond2(stringBounder).getTranslated(dimDiamond2.getPointD()); + final Point2D p2; + final UPolygon arrow; + if (x1 < ptD.getX()) { + p2 = ptD; + arrow = Arrows.asToRight(); + } else if (x1 > ptB.getX()) { + p2 = ptB; + arrow = Arrows.asToLeft(); + } else { + p2 = ptA; + arrow = Arrows.asToDown(); + } + final double x2 = p2.getX(); final double y2 = p2.getY(); - final UPolygon arrow = x2 > x1 ? Arrows.asToRight() : Arrows.asToLeft(); final Snake snake = Snake.create(arrowColor, arrow); snake.addPoint(x1, y1); snake.addPoint(x1, y2); @@ -147,29 +162,8 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds { .getTranslated(getFtile1().calculateDimension(stringBounder).getPointOut()); } - private Point2D getP2(StringBounder stringBounder) { - final FtileGeometry dimDiamond2 = diamond2.calculateDimension(stringBounder); - final Point2D pt; - if (getFtile1() == tiles.get(0)) { - pt = dimDiamond2.getPointD(); - } else if (getFtile1() == tiles.get(tiles.size() - 1)) { - pt = dimDiamond2.getPointB(); - } else { - throw new IllegalStateException(); - } - return getTranslateDiamond2(stringBounder).getTranslated(pt); - - } - } - // protected UTranslate getTranslateOf(Ftile tile, StringBounder stringBounder) - // { - // return getTranslateNude(tile, - // stringBounder).compose(getTranslateMain(stringBounder)); - // - // } - class ConnectionVerticalTop extends AbstractConnection { private final Branch branch; @@ -278,9 +272,14 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds { final List conns = new ArrayList<>(); conns.add(new ConnectionHorizontalThenVertical(tiles.get(0), branches.get(0))); conns.add(new ConnectionHorizontalThenVertical(tiles.get(tiles.size() - 1), branches.get(tiles.size() - 1))); - conns.add(new ConnectionVerticalThenHorizontal(tiles.get(0))); - conns.add(new ConnectionVerticalThenHorizontal(tiles.get(tiles.size() - 1))); - for (int i = 1; i < tiles.size() - 1; i++) { + + final int first = getFirst(stringBounder); + final int last = getLast(stringBounder); + if (first < tiles.size()) + conns.add(new ConnectionVerticalThenHorizontal(tiles.get(first))); + if (last > 0) + conns.add(new ConnectionVerticalThenHorizontal(tiles.get(last))); + for (int i = first + 1; i < last; i++) { final Ftile tile = tiles.get(i); conns.add(new ConnectionVerticalTop(tile, branches.get(i))); if (tile.calculateDimension(stringBounder).hasPointOut()) { @@ -291,4 +290,24 @@ public class FtileSwitchWithManyLinks extends FtileSwitchWithDiamonds { return FtileUtils.addConnection(this, conns); } + private int getFirst(StringBounder stringBounder) { + for (int i = 0; i < tiles.size() - 1; i++) { + final Ftile tile = tiles.get(i); + if (tile.calculateDimension(stringBounder).hasPointOut()) { + return i; + } + } + return tiles.size(); + } + + private int getLast(StringBounder stringBounder) { + for (int i = tiles.size() - 1; i >= 0; i--) { + final Ftile tile = tiles.get(i); + if (tile.calculateDimension(stringBounder).hasPointOut()) { + return i; + } + } + return -1; + } + } diff --git a/src/net/sourceforge/plantuml/asciiart/TextSkin.java b/src/net/sourceforge/plantuml/asciiart/TextSkin.java index 5d609aa1a..fde9821c0 100644 --- a/src/net/sourceforge/plantuml/asciiart/TextSkin.java +++ b/src/net/sourceforge/plantuml/asciiart/TextSkin.java @@ -35,15 +35,18 @@ */ package net.sourceforge.plantuml.asciiart; +import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.sequencediagram.NotePosition; import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.ArrowDirection; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.rose.ComponentRoseGroupingSpace; +import net.sourceforge.plantuml.skin.rose.ComponentRoseNewpage; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.style.Style; @@ -56,7 +59,8 @@ public class TextSkin extends Rose { } @Override - public ArrowComponent createComponentArrow(Style[] styles, ArrowConfiguration config, ISkinParam param, Display stringsToDisplay) { + public ArrowComponent createComponentArrow(Style[] styles, ArrowConfiguration config, ISkinParam param, + Display stringsToDisplay) { if (config.getArrowDirection() == ArrowDirection.LEFT_TO_RIGHT_NORMAL || config.getArrowDirection() == ArrowDirection.RIGHT_TO_LEFT_REVERSE || config.getArrowDirection() == ArrowDirection.BOTH_DIRECTION) { @@ -70,8 +74,23 @@ public class TextSkin extends Rose { } @Override - public Component createComponent(Style style[], ComponentType type, ArrowConfiguration config, - ISkinParam param, Display stringsToDisplay) { + public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param, Display stringsToDisplay, + NotePosition notePosition) { + if (type == ComponentType.NOTE || type == ComponentType.NOTE_BOX) { + return new ComponentTextNote(type, stringsToDisplay, fileFormat); + } + throw new UnsupportedOperationException(type.toString()); + } + + @Override + public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param, + Display stringsToDisplay) { + return createComponentNote(styles, type, param, stringsToDisplay, null); + } + + @Override + public Component createComponent(Style style[], ComponentType type, ArrowConfiguration config, ISkinParam param, + Display stringsToDisplay) { if (type == ComponentType.ACTOR_HEAD || type == ComponentType.ACTOR_TAIL) { return new ComponentTextActor(type, stringsToDisplay, fileFormat, fileFormat == FileFormat.UTXT ? AsciiShape.STICKMAN_UNICODE : AsciiShape.STICKMAN); @@ -85,10 +104,9 @@ public class TextSkin extends Rose { if (type.name().endsWith("_HEAD") || type.name().endsWith("_TAIL")) { return new ComponentTextParticipant(type, stringsToDisplay, fileFormat); } - if (type.isArrow() - && (config.getArrowDirection() == ArrowDirection.LEFT_TO_RIGHT_NORMAL - || config.getArrowDirection() == ArrowDirection.RIGHT_TO_LEFT_REVERSE || config - .getArrowDirection() == ArrowDirection.BOTH_DIRECTION)) { + if (type.isArrow() && (config.getArrowDirection() == ArrowDirection.LEFT_TO_RIGHT_NORMAL + || config.getArrowDirection() == ArrowDirection.RIGHT_TO_LEFT_REVERSE + || config.getArrowDirection() == ArrowDirection.BOTH_DIRECTION)) { return new ComponentTextArrow(type, config, stringsToDisplay, fileFormat, param.maxAsciiMessageLength()); } if (type.isArrow() && config.isSelfArrow()) { @@ -115,9 +133,6 @@ public class TextSkin extends Rose { if (type == ComponentType.ALIVE_BOX_OPEN_OPEN) { return new ComponentTextActiveLine(fileFormat); } - if (type == ComponentType.NOTE || type == ComponentType.NOTE_BOX) { - return new ComponentTextNote(type, stringsToDisplay, fileFormat); - } if (type == ComponentType.DIVIDER) { return new ComponentTextDivider(type, stringsToDisplay, fileFormat); } @@ -130,9 +145,6 @@ public class TextSkin extends Rose { if (type == ComponentType.GROUPING_ELSE) { return new ComponentTextGroupingElse(type, stringsToDisplay, fileFormat); } - if (type == ComponentType.NEWPAGE) { - return new ComponentTextNewpage(fileFormat); - } if (type == ComponentType.DELAY_TEXT) { return new ComponentTextDelay(type, stringsToDisplay, fileFormat); } @@ -141,5 +153,11 @@ public class TextSkin extends Rose { } throw new UnsupportedOperationException(type.toString()); } + + @Override + public Component createComponentNewPage(ISkinParam param) { + return new ComponentTextNewpage(fileFormat); + } + } diff --git a/src/net/sourceforge/plantuml/creole/rosetta/CreoleParser2.java b/src/net/sourceforge/plantuml/creole/rosetta/CreoleParser2.java deleted file mode 100644 index 731ae3b81..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/CreoleParser2.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, Arnaud Roques - * - * Project Info: http://plantuml.com - * - * If you like this project or if you find it useful, you can support us at: - * - * http://plantuml.com/patreon (only 1$ per month!) - * http://plantuml.com/paypal - * - * This file is part of PlantUML. - * - * PlantUML is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * PlantUML distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * - * Original Author: Arnaud Roques - * - * - */ -package net.sourceforge.plantuml.creole.rosetta; - -import java.util.Objects; - -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 = Objects.requireNonNull(skinParam); - 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 deleted file mode 100644 index 9b2979309..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/ReaderAbstractWiki.java +++ /dev/null @@ -1,105 +0,0 @@ -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 deleted file mode 100644 index ee48960be..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/ReaderCreole.java +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index dfda9ee5c..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/ReaderDokuwiki.java +++ /dev/null @@ -1,326 +0,0 @@ -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 deleted file mode 100644 index 40e907f4d..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/ReaderWiki.java +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index cfca2b045..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/Rosetta.java +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100644 index 3cfaa7ec3..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/StripeRow.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, Arnaud Roques - * - * Project Info: http://plantuml.com - * - * If you like this project or if you find it useful, you can support us at: - * - * http://plantuml.com/patreon (only 1$ per month!) - * http://plantuml.com/paypal - * - * This file is part of PlantUML. - * - * PlantUML is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * PlantUML distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * - * Original Author: Arnaud Roques - * - * - */ -package net.sourceforge.plantuml.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.creole.legacy.AtomTextUtils; -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(AtomTextUtils.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(AtomTextUtils.create(tmp.toString(), fontConfiguration)); - } - return result; - } - -} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/WikiLanguage.java b/src/net/sourceforge/plantuml/creole/rosetta/WikiLanguage.java deleted file mode 100644 index 28e176057..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/WikiLanguage.java +++ /dev/null @@ -1,110 +0,0 @@ -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 deleted file mode 100644 index e7fe31ae3..000000000 --- a/src/net/sourceforge/plantuml/creole/rosetta/WriterWiki.java +++ /dev/null @@ -1,28 +0,0 @@ -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/BodierLikeClassOrObject.java b/src/net/sourceforge/plantuml/cucadiagram/BodierLikeClassOrObject.java index b01796a84..655fbd5bf 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodierLikeClassOrObject.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodierLikeClassOrObject.java @@ -166,15 +166,19 @@ public class BodierLikeClassOrObject implements Bodier { public boolean hasUrl() { for (CharSequence cs : getFieldsToDisplay()) { - final Member m = (Member) cs; - if (m.hasUrl()) { - return true; + if (cs instanceof Member) { + final Member m = (Member) cs; + if (m.hasUrl()) { + return true; + } } } for (CharSequence cs : getMethodsToDisplay()) { - final Member m = (Member) cs; - if (m.hasUrl()) { - return true; + if (cs instanceof Member) { + final Member m = (Member) cs; + if (m.hasUrl()) { + return true; + } } } return false; diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index 320b04038..f608f8986 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -70,28 +70,29 @@ public class PSystemDonors extends PlainDiagram { private static final int COLS = 6; private static final int FREE_LINES = 6; - public static final String DONORS = "6wOD0AmFjCllA6nYeh4EstErPvQF9MScYM1vdb2SMCJfBY3-0FTEZ_kDz1VHbTtxfXbHwxL9EOEeFWXw" + public static final String DONORS = "6zeD0AmFjCllA6nYeh4EstErPvQF9MScYM1vdb2SMCJfBY3-0FTEZ_kDz1VHbUvzqunHwxL9EOEeFWXw" + "mBlRGljG-byVX3bBNWHtfWGNa0AYEBf4VgGRsKwVL1bIWcUfwEzlcRYztJekL2Q9lX7AWU9-EMJWRVfi" - + "dft6eD4BL1_-zf1sN_s_gRDrUIY4MRfRWH4O5OrmN5ycSw__erfKE0KxXnfs-Z6Tkg0w7AfLYSssDqMq" - + "akQEMQ6-dOzQJIwAaLAa-6iZ3RyOJ6ZCoUoJv9T-qVYbRiA7rkeQOjm1n3bJEhfkw-ryF8Zb5qby2F84" - + "Nr2im1n8ET8lejcvwK73mu6XVXVLsDB2FKzI894DBUJDFugaq7k8iylWfk5L0GA_Tr21P0ngr8Ip0tS3" - + "Akd15fqQkEfYVs5fMOVbAJsJXgSH2oyBQW4r14aCUa5dz9LRfkvvA1m9UKhYEMqLwi-2Tz0s5_IDBIK1" - + "wslxgLcIF-AKhOSq7RdF-LTd1xnhoChLRyOSaPoWAIzpGPblBL0_0Zqq9so9xrNkBCGXr4VgfW-TQmwr" - + "Yd12BYaLw-Hbjhsc_w4hPx914PuE5laz-UjYKnnieQibDS0RMYKqwtm2IGtrzvSyNZhV1TUKIDmR4Mr4" - + "TWtHVp-tD3CK1-ZWDBEXcoPO1gkqwYYs888zGiS7t2Ga1-5ycbpsf-MNw2q_0V1c4a5ts0WqWT-_k3Ba" - + "o8KqaAbhqrm0R3sjr8k6poCCAdG8kXLLmkbjxleP9erjoyQMPT8kdhSRZ94Vqt75XUKobyW8mnArQDOV" - + "rWxHBi5LFaxoglTCSXNWKk4zQkFUlsJ0pZ1d859ikkFnIDjY6UgmcCMUwwKkkgVRoS53jnoucqLpc54c" - + "3va6WoE9gActYFhGOFYRG5Qprnfqds1hkCuC7cQamUkfoGqrEQRXiPtbEDaYH8QvUCKf8bnGi9Tb9pcw" - + "bf1onEfnICZlH9z4f4fVA8tOkTnLU4RsACZ3UO-iUjIFAPXSG9KnJH2M5gmvGz0UjXR8m5f5psmRnEwN" - + "TYoOs_pan8f3yHKJRJTkK305PeOmRXX4eZBGAAKNdoGYyDqVTwidrpgiuxjxMZ4EaXQI2AX2cSxyGJLJ" - + "Jpr2qrYlyVzjhRqiEt_-jKSsEJNPQ-yXYDP1J00Yl42NSdyGmLFWwys6cO1Jh62Y9mbNhbbw6aXOi8K-" - + "k8awsMOqRxnORbmkMdj-g9AVvdQuc0s-8ST5E6YVVOaghRtKWuhOlkLTXviS1lukgWoBvB9NpsGaT1Ag" - + "EBV7RZCLpLXbW1NCWTe4zkx-h4pZAMFkLo1LXYj0ljkG8QdHGmjhQbeH5m9hf7DxRsuRuep-BnZeHxJM" - + "pxrwQ3p9rVKN4uLlHmZZd4ZYSf5u8CAufUP4Wnw-2I8VL0jbO6d733jti49-Wp_66mb7xE03JZtceZpj" - + "XHnZ2zaxPu4_8NWFeO4iB5RgLSH2ASS3APA2EQjbB4FQILjmLcy0dQ9W_F_UXd1wela5cLtcrHl9N8wv" - + "brGGwN1_5ebDIxO6vC2-bBbiwuhSphb8Xvtu7_YEyvsFg5iN4IY1A2N1QpCXtztOfzh4flHShy5nNER5" - + "mUGNiYlQ-PA1hR7OWYndCr3m902rWqA5oglmg_qJrvmpvDzxzr8OQCBpr6rquxaNJ8iLI_2KDA3c9alW" - + "slTxRh8uK3ZHsE32KdEZXqazMkPJxRXfivuCAf6xL4pq2BERbgZo4rrFgiiXKxTUKBCajAux4tJosnRa" + "qhLppmip9EnB2W00"; + + "dft6XqOlK0t-zf1sN_tVfRDrULKLfWNThS08Z3gDSAJiDVwFQb575Em4DUpqOpgLgreErQh4PjkR8bf9" + + "SyUiqD3EHvqc5yLaf4ZnraOANZ6OeIadiq-HN_f5uu-w2HrQgsk8vGuWpfdIe-kstgx7WrX-iSG7mHLy" + + "GHQ1EP1o95v4otFJZOQB1muDkwZ6bfNSyyGAGIgqa3V_A9AItaCykmnk6curGE3rDWf8ng0cJJZRTpUW" + + "qXviqQM1gwxr5-RMTLYUoisauGd4mis2Ma0DGUA3Nj0PVUMMoJqFXIqXJqayfwr6_Pbu9srpGT_uKX8m" + + "NpjFpSp-Y56s7j8uSf_phyuEUDUGbQlVZ3d2EOEwlCm5CTzQe7u4UcnEM1BVK-uif23KH-gc3vrhJseL" + + "uPHSKYhMwKjiUItt3rrfams9vEbWoNotV5rhYWTRw2ga6dX3gpJDEb_0f8Rw-qiUBPtlWcjAnUuDYpOY" + + "kuRelvzRcXcA0tHeYjdGJG26iKghpc834UmMEZRW9e4SXF9fSicVbb-Yj_m4m5jA15rXGz8CVlzIyf23" + + "2p6GgUjIN00idbBgHSFZ0GkLEWJTZYgXz3Pt_GoJbctBni8oQHVFEmt6o8_fbEB2V9bBU8HXgLeqvpwi" + + "7S0kmRFvECshxZFDLO1BXVUOZMl_ae4ymvmHaQBJ5Oz7sXRpK8TX5cFEIrrqJxUJWuTkFN0sY-OneqmU" + + "iXmO74v6JRr5w4E3uMyAsHnxhKNr2RQ7w_JWPaOUl9wQt5AJ8neksrcEdIq2aip5AtPHuVo2jImZcQDh" + + "2P4ZLaz2XlnEzKbOgiI5fWaxbxi6psHw5EJXl2TMFUh757GkeAgO9WX92sRE49I7hGKoi5RHCzS6iVkb" + + "7GlwDZyvSPP3yMKJxJHkoC8Kc1uYlU4W4ZC7iXAzr2GHm7T_tArUPgr37D_TqufnaBIGn40LcTFfFoWp" + + "zTOZD8tr5ltVrjhBilFdNsjaarEplVOUWcWT90KWmWjqb0j214-1hpSR9WDEM255Jp9SkMxfUI1XmLRw" + + "u2RgT9jHl-F5SXDoqThpGvN-DBKeEEiRKbo4WlBPboXfxQKULDJshMySRd8m_5rKcPJ9lRsCfib8-0Ig" + + "E7V7RZCLzTYi0IAO0vK9ZDtzMPd6KyRShr2g3Cy4ylqM6PAC7bfOKzFAk11OAvtRUolR4C_e_u8H_QZM" + + "kUTUFJITvEe6YeZ2jod8k22Ik5oa7GYmcsjEFEZc6p_oGRLG1fPspR1p1YlaD_GZl95mp3O-KEGn5ytJ" + + "NiXXMyZUDGly2S1x20zaOR5Aho8MIZaUI94Kp5ajarcadRG5f_GEe5CKZF_VEn0kDz7yYimky-gDP2xJ" + + "t8yhY7ouFul4fYLR8t9WFoDpsVOLkLrpaGuxzJ_m7UUx7r6tBoB82iIC97Zj9gIx6tjKczZCU6xGu3Wk" + + "y-DWyelO5Uq2oS3ML6n1Lh8PAF4a1BL39XLclP9VtHzSSowHV-_TIs6W2Sypjz2Dv_fW5TbQYwUa0JKt" + + "MNpNlZzm9uiJ2YSU2rnO9cxqCALRotogNJTjDf169NALYl4UPdRJ4YK_qVMakXmokVM2cYMXTTsPeZCu" + + "jWLpwTgvvuKPNEetKtqcfCT0m_Mb1W00"; /* * Special thanks to our sponsors and donors: diff --git a/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java b/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java index c66f51447..be487fb10 100644 --- a/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java +++ b/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java @@ -289,7 +289,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker { final HColor borderColor = HColorUtils.BLACK; decoration.drawU(ug.apply(new UTranslate(corner)), backColor, borderColor, shadowing, roundCorner, - skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false), + skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null), skinParam.getStereotypeAlignment()); // // Print a simple rectangle right now diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index 982148595..ab566b4e8 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -67,14 +67,14 @@ public class QuoteUtils { "Gur obl vf vzcbegnag. Ur unf gb yvir.", "Bapr hcba n gvzr va n tnynkl sne, sne njnl...", "Naq lbh xabj gurer'f n ybat ybat jnl nurnq bs lbh...", "Na nyyretl gb bkltra? Ryz oyvtug?", "Ohg nybef lbh ner Serapu!", "A'nv-wr qbap gnag irph dhr cbhe prggr vasnzvr?", - "Fbzrguvat vf ebggra va gur Fgngr bs Qraznex.", "Url, jung qb lbh jnag? Zvenpyrf?", - "1.21 tvtnjnggf! 1.21 tvtnjnggf. Terng Fpbgg! ", "Jung gur uryy vf n tvtnjngg?", "V arrq n inpngvba.", - "Ba qrienvg wnznvf dhvggre Zbagnhona.", "Zl sbepr vf n cyngsbez gung lbh pna pyvzo ba...", - "Gurer'f fbzrguvat jrveq, naq vg qba'g ybbx tbbq...", "Rg evra ienvzrag ar punatr znvf gbhg rfg qvssrerag", - "Ornz zr hc, Fpbggl.", "Gurer vf ab fcbba.", "Sbyybj gur juvgr enoovg.", - "Arire fraq n uhzna gb qb n znpuvar'f wbo.", "Theh zrqvgngvba. Cerff yrsg zbhfr ohggba gb pbagvahr.", - "V qba'g guvax jr'er va Xnafnf nalzber.", "Yhxr, V nz lbhe sngure.", "Oybbq, Fjrng naq Grnef", - "Ubhfgba, jr unir n ceboyrz.", "Xrlobneq snvyher, cerff nal xrl gb pbagvahr", "Ovt zvfgnxr!", + "Url, jung qb lbh jnag? Zvenpyrf?", "1.21 tvtnjnggf! 1.21 tvtnjnggf. Terng Fpbgg! ", + "Jung gur uryy vf n tvtnjngg?", "V arrq n inpngvba.", "Ba qrienvg wnznvf dhvggre Zbagnhona.", + "Zl sbepr vf n cyngsbez gung lbh pna pyvzo ba...", "Gurer'f fbzrguvat jrveq, naq vg qba'g ybbx tbbq...", + "Rg evra ienvzrag ar punatr znvf gbhg rfg qvssrerag", "Ornz zr hc, Fpbggl.", "Gurer vf ab fcbba.", + "Sbyybj gur juvgr enoovg.", "Arire fraq n uhzna gb qb n znpuvar'f wbo.", + "Theh zrqvgngvba. Cerff yrsg zbhfr ohggba gb pbagvahr.", "V qba'g guvax jr'er va Xnafnf nalzber.", + "Yhxr, V nz lbhe sngure.", "Oybbq, Fjrng naq Grnef", "Ubhfgba, jr unir n ceboyrz.", + "Xrlobneq snvyher, cerff nal xrl gb pbagvahr", "Ovt zvfgnxr!", "Ubj znal HZY qrfvtaref qbrf vg gnxr gb punatr n yvtugohyo ?", "Qb lbh yvxr zbivrf nobhg tynqvngbef ?", "Gur fcvevg bs yrneavat vf n ynfgvat sebagvre.", "Vg vf phevbhf sbe fnvybef guvf arrq sbe znxvat fragraprf.", "Ubcvat sbe gur orfg, ohg rkcrpgvat gur jbefg", @@ -295,7 +295,10 @@ public class QuoteUtils { "V'z shmml ba gur jubyr tbbq/onq guvat. Jung qb lbh zrna, 'onq'?", "Lbh'er evtug. Ab uhzna orvat jbhyq fgnpx obbxf yvxr guvf.", "V nz fb pyrire gung fbzrgvzrf V qba'g haqrefgnaq n fvatyr jbeq bs jung V nz fnlvat.", - "Jnxr zr hc orsber lbh tb-tb"); + "Jnxr zr hc orsber lbh tb-tb", + "Fbzrguvat vf ebggra va gur fgngr bs Qraznex! Naq, Unzyrg vf gnxvat bhg gur genfu!", + "Bu bhv, cneybaf-ra qrf pbcnvaf, cbhe sbhger yn zreqr vyf fbag punzcvbaf", "Gjb qnlf gb ergverzrag!", + "Gh nf qrf qbvtgf ? Pebvfrf-ra ha znk g'nf vagrerg !"); private QuoteUtils() { } diff --git a/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java b/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java new file mode 100644 index 000000000..56e877c6f --- /dev/null +++ b/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java @@ -0,0 +1,972 @@ +/* ======================================================================== + * 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. + * + * + * Translated and refactored by: Arnaud Roques + * + * + */ + +/* +This is a Java port of https://github.com/asciimath/asciimathml/blob/master/asciimath-based/ASCIIMathTeXImg.js + +ASCIIMathTeXImg.js itself is based on ASCIIMathML, Version 1.4.7 Aug 30, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen +Modified with TeX conversion for IMG rendering Sept 6, 2006 (c) David Lippman http://www.pierce.ctc.edu/dlippman + Updated to match ver 2.2 Mar 3, 2014 + Latest at https://github.com/mathjax/asciimathml + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +package net.sourceforge.plantuml.math; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class ASCIIMathTeXImg { + + private int AMnestingDepth; + private int AMpreviousSymbol; + private int AMcurrentSymbol; + + private String slice(String str, int start, int end) { + if (end > str.length()) { + return str.substring(start); + } + return str.substring(start, end); + } + + private String slice(String str, int start) { + return str.substring(start); + } + + private String substr(String str, int pos, int len) { + if (pos + len > str.length()) { + return str.substring(pos); + } + return str.substring(pos, pos + len); + } + + static private final int CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, RIGHTBRACKET = 5, SPACE = 6, + UNDEROVER = 7, DEFINITION = 8, LEFTRIGHT = 9, TEXT = 10; // token types + + static class Tupple { + private final String input; + private final String tag; + private final String output; + private final String tex; + private final int ttype; + + private final String[] rewriteleftright; + private final Collection flags; + + private Tupple(String[] rewriteleftright, String input, String tag, String output, String tex, int ttype, + String... flags) { + this.input = input; + this.tag = tag; + this.output = output; + this.tex = tex; + this.ttype = ttype; + this.flags = Arrays.asList(flags); + this.rewriteleftright = rewriteleftright; + } + + private Tupple(String input, String tag, String output, String tex, int ttype, String... flags) { + this.input = input; + this.tag = tag; + this.output = output; + this.tex = tex; + this.ttype = ttype; + this.flags = Arrays.asList(flags); + this.rewriteleftright = null; + } + + public boolean hasFlag(String flagName) { + return flags.contains(flagName); + } + } + + private static final Tupple AMsqrt = new Tupple("sqrt", "msqrt", "sqrt", null, UNARY); + private static final Tupple AMroot = new Tupple("root", "mroot", "root", null, BINARY); + private static final Tupple AMfrac = new Tupple("frac", "mfrac", "/", null, BINARY); + private static final Tupple AMdiv = new Tupple("/", "mfrac", "/", null, INFIX); + private static final Tupple AMover = new Tupple("stackrel", "mover", "stackrel", null, BINARY); + private static final Tupple AMsub = new Tupple("_", "msub", "_", null, INFIX); + private static final Tupple AMsup = new Tupple("^", "msup", "^", null, INFIX); + private static final Tupple AMtext = new Tupple("text", "mtext", "text", null, TEXT); + private static final Tupple AMmbox = new Tupple("mbox", "mtext", "mbox", null, TEXT); + private static final Tupple AMquote = new Tupple("\"", "mtext", "mbox", null, TEXT); + + private static final List AMsymbols = new ArrayList<>(Arrays.asList(new Tupple[] { // + // some greek symbols + new Tupple("alpha", "mi", "\u03B1", null, CONST), // + new Tupple("beta", "mi", "\u03B2", null, CONST), // + new Tupple("chi", "mi", "\u03C7", null, CONST), // + new Tupple("delta", "mi", "\u03B4", null, CONST), // + new Tupple("Delta", "mo", "\u0394", null, CONST), // + new Tupple("epsi", "mi", "\u03B5", "epsilon", CONST), // + new Tupple("varepsilon", "mi", "\u025B", null, CONST), // + new Tupple("eta", "mi", "\u03B7", null, CONST), // + new Tupple("gamma", "mi", "\u03B3", null, CONST), // + new Tupple("Gamma", "mo", "\u0393", null, CONST), // + new Tupple("iota", "mi", "\u03B9", null, CONST), // + new Tupple("kappa", "mi", "\u03BA", null, CONST), // + new Tupple("lambda", "mi", "\u03BB", null, CONST), // + new Tupple("Lambda", "mo", "\u039B", null, CONST), // + new Tupple("lamda", "mi", "lambda", null, DEFINITION), // + new Tupple("Lamda", "mi", "Lambda", null, DEFINITION), // + new Tupple("mu", "mi", "\u03BC", null, CONST), // + new Tupple("nu", "mi", "\u03BD", null, CONST), // + new Tupple("omega", "mi", "\u03C9", null, CONST), // + new Tupple("Omega", "mo", "\u03A9", null, CONST), // + new Tupple("phi", "mi", "\u03C6", null, CONST), // + new Tupple("varphi", "mi", "\u03D5", null, CONST), // + new Tupple("Phi", "mo", "\u03A6", null, CONST), // + new Tupple("pi", "mi", "\u03C0", null, CONST), // + new Tupple("Pi", "mo", "\u03A0", null, CONST), // + new Tupple("psi", "mi", "\u03C8", null, CONST), // + new Tupple("Psi", "mi", "\u03A8", null, CONST), // + new Tupple("rho", "mi", "\u03C1", null, CONST), // + new Tupple("sigma", "mi", "\u03C3", null, CONST), // + new Tupple("Sigma", "mo", "\u03A3", null, CONST), // + new Tupple("tau", "mi", "\u03C4", null, CONST), // + new Tupple("theta", "mi", "\u03B8", null, CONST), // + new Tupple("vartheta", "mi", "\u03D1", null, CONST), // + new Tupple("Theta", "mo", "\u0398", null, CONST), // + new Tupple("upsilon", "mi", "\u03C5", null, CONST), // + new Tupple("xi", "mi", "\u03BE", null, CONST), // + new Tupple("Xi", "mo", "\u039E", null, CONST), // + new Tupple("zeta", "mi", "\u03B6", null, CONST), // + + // binary operation symbols + new Tupple("*", "mo", "\u22C5", "cdot", CONST), // + new Tupple("**", "mo", "\u2217", "ast", CONST), // + new Tupple("***", "mo", "\u22C6", "star", CONST), // + new Tupple("//", "mo", "/", "/", CONST, "val", "notexcopy"), // + new Tupple("\\\\", "mo", "\\", "backslash", CONST), // + new Tupple("setminus", "mo", "\\", null, CONST), // + new Tupple("xx", "mo", "\u00D7", "times", CONST), // + new Tupple("|><", "mo", "\u22C9", "ltimes", CONST), // + new Tupple("><|", "mo", "\u22CA", "rtimes", CONST), // + new Tupple("|><|", "mo", "\u22C8", "bowtie", CONST), // + new Tupple("-:", "mo", "\u00F7", "div", CONST), // + new Tupple("divide", "mo", "-:", null, DEFINITION), // + new Tupple("@", "mo", "\u2218", "circ", CONST), // + new Tupple("o+", "mo", "\u2295", "oplus", CONST), // + new Tupple("ox", "mo", "\u2297", "otimes", CONST), // + new Tupple("o.", "mo", "\u2299", "odot", CONST), // + new Tupple("sum", "mo", "\u2211", null, UNDEROVER), // + new Tupple("prod", "mo", "\u220F", null, UNDEROVER), // + new Tupple("^^", "mo", "\u2227", "wedge", CONST), // + new Tupple("^^^", "mo", "\u22C0", "bigwedge", UNDEROVER), // + new Tupple("vv", "mo", "\u2228", "vee", CONST), // + new Tupple("vvv", "mo", "\u22C1", "bigvee", UNDEROVER), // + new Tupple("nn", "mo", "\u2229", "cap", CONST), // + new Tupple("nnn", "mo", "\u22C2", "bigcap", UNDEROVER), // + new Tupple("uu", "mo", "\u222A", "cup", CONST), // + new Tupple("uuu", "mo", "\u22C3", "bigcup", UNDEROVER), // + new Tupple("overset", "mover", "stackrel", null, BINARY), // + new Tupple("underset", "munder", "stackrel", null, BINARY), // + + // binary relation symbols + new Tupple("!=", "mo", "\u2260", "ne", CONST), // + new Tupple(":=", "mo", ":=", null, CONST), // + new Tupple("lt", "mo", "<", null, CONST), // + new Tupple("gt", "mo", ">", null, CONST), // + new Tupple("<=", "mo", "\u2264", "le", CONST), // + new Tupple("lt=", "mo", "\u2264", "leq", CONST), // + new Tupple("gt=", "mo", "\u2265", "geq", CONST), // + new Tupple(">=", "mo", "\u2265", "ge", CONST), // + new Tupple("-<", "mo", "\u227A", "prec", CONST), // + new Tupple("-lt", "mo", "\u227A", null, CONST), // + new Tupple(">-", "mo", "\u227B", "succ", CONST), // + new Tupple("-<=", "mo", "\u2AAF", "preceq", CONST), // + new Tupple(">-=", "mo", "\u2AB0", "succeq", CONST), // + new Tupple("in", "mo", "\u2208", null, CONST), // + new Tupple("!in", "mo", "\u2209", "notin", CONST), // + new Tupple("sub", "mo", "\u2282", "subset", CONST), // + new Tupple("sup", "mo", "\u2283", "supset", CONST), // + new Tupple("sube", "mo", "\u2286", "subseteq", CONST), // + new Tupple("supe", "mo", "\u2287", "supseteq", CONST), // + new Tupple("-=", "mo", "\u2261", "equiv", CONST), // + new Tupple("~=", "mo", "\u2245", "stackrel{\\sim}{=}", CONST), // + new Tupple("cong", "mo", "~=", null, DEFINITION), // + new Tupple("~~", "mo", "\u2248", "approx", CONST), // + new Tupple("prop", "mo", "\u221D", "propto", CONST), // + + // logical symbols + new Tupple("and", "mtext", "and", null, SPACE), // + new Tupple("or", "mtext", "or", null, SPACE), // + new Tupple("not", "mo", "\u00AC", "neg", CONST), // + new Tupple("=>", "mo", "\u21D2", "Rightarrow", CONST), // + new Tupple("implies", "mo", "=>", null, DEFINITION), // + new Tupple("if", "mo", "if", null, SPACE), // + new Tupple("<=>", "mo", "\u21D4", "Leftrightarrow", CONST), // + new Tupple("iff", "mo", "<=>", null, DEFINITION), // + new Tupple("AA", "mo", "\u2200", "forall", CONST), // + new Tupple("EE", "mo", "\u2203", "exists", CONST), // + new Tupple("_|_", "mo", "\u22A5", "bot", CONST), // + new Tupple("TT", "mo", "\u22A4", "top", CONST), // + new Tupple("|--", "mo", "\u22A2", "vdash", CONST), // + new Tupple("|==", "mo", "\u22A8", "models", CONST), // + + // grouping brackets + new Tupple("(", "mo", "(", null, LEFTBRACKET, "val"), // + new Tupple(")", "mo", ")", null, RIGHTBRACKET, "val"), // + new Tupple("[", "mo", "[", null, LEFTBRACKET, "val"), // + new Tupple("]", "mo", "]", null, RIGHTBRACKET, "val"), // + new Tupple("{", "mo", "{", "lbrace", LEFTBRACKET), // + new Tupple("}", "mo", "}", "rbrace", RIGHTBRACKET), // + new Tupple("|", "mo", "|", null, LEFTRIGHT, "val"), // + new Tupple("(:", "mo", "\u2329", "langle", LEFTBRACKET), // + new Tupple(":)", "mo", "\u232A", "rangle", RIGHTBRACKET), // + new Tupple("<<", "mo", "\u2329", "langle", LEFTBRACKET), // + new Tupple(">>", "mo", "\u232A", "rangle", RIGHTBRACKET), // + new Tupple("{:", "mo", "{:", null, LEFTBRACKET, "invisible"), // + new Tupple(":}", "mo", ":}", null, RIGHTBRACKET, "invisible"), // + + // miscellaneous symbols + new Tupple("int", "mo", "\u222B", null, CONST), // + new Tupple("dx", "mi", "{:d x:}", null, DEFINITION), // + new Tupple("dy", "mi", "{:d y:}", null, DEFINITION), // + new Tupple("dz", "mi", "{:d z:}", null, DEFINITION), // + new Tupple("dt", "mi", "{:d t:}", null, DEFINITION), // + new Tupple("oint", "mo", "\u222E", null, CONST), // + new Tupple("del", "mo", "\u2202", "partial", CONST), // + new Tupple("grad", "mo", "\u2207", "nabla", CONST), // + new Tupple("+-", "mo", "\u00B1", "pm", CONST), // + new Tupple("O/", "mo", "\u2205", "emptyset", CONST), // + new Tupple("oo", "mo", "\u221E", "infty", CONST), // + new Tupple("aleph", "mo", "\u2135", null, CONST), // + new Tupple("...", "mo", "...", "ldots", CONST), // + new Tupple(":.", "mo", "\u2234", "therefore", CONST), // + new Tupple(":'", "mo", "\u2235", "because", CONST), // + new Tupple("/_", "mo", "\u2220", "angle", CONST), // + new Tupple("/_\\", "mo", "\u25B3", "triangle", CONST), // + new Tupple("\\ ", "mo", "\u00A0", null, CONST, "val"), // + new Tupple("frown", "mo", "\u2322", null, CONST), // + new Tupple("%", "mo", "%", "%", CONST, "notexcopy"), // + new Tupple("quad", "mo", "\u00A0\u00A0", null, CONST), // + new Tupple("qquad", "mo", "\u00A0\u00A0\u00A0\u00A0", null, CONST), // + new Tupple("cdots", "mo", "\u22EF", null, CONST), // + new Tupple("vdots", "mo", "\u22EE", null, CONST), // + new Tupple("ddots", "mo", "\u22F1", null, CONST), // + new Tupple("diamond", "mo", "\u22C4", null, CONST), // + new Tupple("square", "mo", "\u25A1", "boxempty", CONST), // + new Tupple("|__", "mo", "\u230A", "lfloor", CONST), // + new Tupple("__|", "mo", "\u230B", "rfloor", CONST), // + new Tupple("|~", "mo", "\u2308", "lceil", CONST), // + new Tupple("lceiling", "mo", "|~", null, DEFINITION), // + new Tupple("~|", "mo", "\u2309", "rceil", CONST), // + new Tupple("rceiling", "mo", "~|", null, DEFINITION), // + new Tupple("CC", "mo", "\u2102", "mathbb{C}", CONST, "notexcopy"), // + new Tupple("NN", "mo", "\u2115", "mathbb{N}", CONST, "notexcopy"), // + new Tupple("QQ", "mo", "\u211A", "mathbb{Q}", CONST, "notexcopy"), // + new Tupple("RR", "mo", "\u211D", "mathbb{R}", CONST, "notexcopy"), // + new Tupple("ZZ", "mo", "\u2124", "mathbb{Z}", CONST, "notexcopy"), // + new Tupple("f", "mi", "f", null, UNARY, "func", "val"), // + new Tupple("g", "mi", "g", null, UNARY, "func", "val"), // + new Tupple("''", "mo", "''", null, 0, "val"), // + new Tupple("'''", "mo", "'''", null, 0, "val"), // + new Tupple("''''", "mo", "''''", null, 0, "val"), // + + // standard functions + new Tupple("lim", "mo", "lim", null, UNDEROVER), // + new Tupple("Lim", "mo", "Lim", null, UNDEROVER), // + new Tupple("sin", "mo", "sin", null, UNARY, "func"), // + new Tupple("cos", "mo", "cos", null, UNARY, "func"), // + new Tupple("tan", "mo", "tan", null, UNARY, "func"), // + new Tupple("arcsin", "mo", "arcsin", null, UNARY, "func"), // + new Tupple("arccos", "mo", "arccos", null, UNARY, "func"), // + new Tupple("arctan", "mo", "arctan", null, UNARY, "func"), // + new Tupple("sinh", "mo", "sinh", null, UNARY, "func"), // + new Tupple("cosh", "mo", "cosh", null, UNARY, "func"), // + new Tupple("tanh", "mo", "tanh", null, UNARY, "func"), // + new Tupple("cot", "mo", "cot", null, UNARY, "func"), // + new Tupple("coth", "mo", "coth", null, UNARY, "func"), // + new Tupple("sech", "mo", "sech", null, UNARY, "func"), // + new Tupple("csch", "mo", "csch", null, UNARY, "func"), // + new Tupple("sec", "mo", "sec", null, UNARY, "func"), // + new Tupple("csc", "mo", "csc", null, UNARY, "func"), // + new Tupple("log", "mo", "log", null, UNARY, "func"), // + new Tupple("ln", "mo", "ln", null, UNARY, "func"), // + new Tupple(new String[] { "|", "|" }, "abs", "mo", "abs", null, UNARY, "notexcopy"), // + new Tupple(new String[] { "\\|", "\\|" }, "norm", "mo", "norm", null, UNARY, "notexcopy"), // + new Tupple(new String[] { "\\lfloor", "\\rfloor" }, "floor", "mo", "floor", null, UNARY, "notexcopy"), // + new Tupple(new String[] { "\\lceil", "\\rceil" }, "ceil", "mo", "ceil", null, UNARY, "notexcopy"), // + new Tupple("Sin", "mo", "sin", null, UNARY, "func"), // + new Tupple("Cos", "mo", "cos", null, UNARY, "func"), // + new Tupple("Tan", "mo", "tan", null, UNARY, "func"), // + new Tupple("Arcsin", "mo", "arcsin", null, UNARY, "func"), // + new Tupple("Arccos", "mo", "arccos", null, UNARY, "func"), // + new Tupple("Arctan", "mo", "arctan", null, UNARY, "func"), // + new Tupple("Sinh", "mo", "sinh", null, UNARY, "func"), // + new Tupple("Sosh", "mo", "cosh", null, UNARY, "func"), // + new Tupple("Tanh", "mo", "tanh", null, UNARY, "func"), // + new Tupple("Cot", "mo", "cot", null, UNARY, "func"), // + new Tupple("Sec", "mo", "sec", null, UNARY, "func"), // + new Tupple("Csc", "mo", "csc", null, UNARY, "func"), // + new Tupple("Log", "mo", "log", null, UNARY, "func"), // + new Tupple("Ln", "mo", "ln", null, UNARY, "func"), // + new Tupple(new String[] { "|", "|" }, "Abs", "mo", "abs", null, UNARY, "notexcopy"), // + new Tupple("det", "mo", "det", null, UNARY, "func"), // + new Tupple("exp", "mo", "exp", null, UNARY, "func"), // + new Tupple("dim", "mo", "dim", null, CONST), // + new Tupple("mod", "mo", "mod", "text{mod}", CONST, "notexcopy"), // + new Tupple("gcd", "mo", "gcd", null, UNARY, "func"), // + new Tupple("lcm", "mo", "lcm", "text{lcm}", UNARY, "func", "notexcopy"), // + new Tupple("lub", "mo", "lub", null, CONST), // + new Tupple("glb", "mo", "glb", null, CONST), // + new Tupple("min", "mo", "min", null, UNDEROVER), // + new Tupple("max", "mo", "max", null, UNDEROVER), // + + // arrows + new Tupple("uarr", "mo", "\u2191", "uparrow", CONST), // + new Tupple("darr", "mo", "\u2193", "downarrow", CONST), // + new Tupple("rarr", "mo", "\u2192", "rightarrow", CONST), // + new Tupple("->", "mo", "\u2192", "to", CONST), // + new Tupple(">->", "mo", "\u21A3", "rightarrowtail", CONST), // + new Tupple("->>", "mo", "\u21A0", "twoheadrightarrow", CONST), // + new Tupple(">->>", "mo", "\u2916", "twoheadrightarrowtail", CONST), // + new Tupple("|->", "mo", "\u21A6", "mapsto", CONST), // + new Tupple("larr", "mo", "\u2190", "leftarrow", CONST), // + new Tupple("harr", "mo", "\u2194", "leftrightarrow", CONST), // + new Tupple("rArr", "mo", "\u21D2", "Rightarrow", CONST), // + new Tupple("lArr", "mo", "\u21D0", "Leftarrow", CONST), // + new Tupple("hArr", "mo", "\u21D4", "Leftrightarrow", CONST), // + + // commands with argument + AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup, + new Tupple("cancel", "menclose", "cancel", null, UNARY), // + new Tupple("Sqrt", "msqrt", "sqrt", null, UNARY), // + new Tupple("hat", "mover", "\u005E", null, UNARY, "acc"), // + new Tupple("bar", "mover", "\u00AF", "overline", UNARY, "acc"), // + new Tupple("vec", "mover", "\u2192", null, UNARY, "acc"), // + new Tupple("tilde", "mover", "~", null, UNARY, "acc"), // + new Tupple("dot", "mover", ".", null, UNARY, "acc"), // + new Tupple("ddot", "mover", "..", null, UNARY, "acc"), // + new Tupple("ul", "munder", "\u0332", "underline", UNARY, "acc"), // + new Tupple("ubrace", "munder", "\u23DF", "underbrace", UNARY, "acc"), // + new Tupple("obrace", "mover", "\u23DE", "overbrace", UNARY, "acc"), // + AMtext, AMmbox, AMquote, // + new Tupple("color", "mstyle", null, null, BINARY), // + } // + )); + + private static String[] AMnames; + + private static void AMinitSymbols() { + int symlen = AMsymbols.size(); + for (int i = 0; i < symlen; i++) { + if (AMsymbols.get(i).tex != null && !(AMsymbols.get(i).hasFlag("notexcopy"))) { + Tupple tmp = AMsymbols.get(i).hasFlag("acc") + ? new Tupple(AMsymbols.get(i).tex, AMsymbols.get(i).tag, AMsymbols.get(i).output, null, + AMsymbols.get(i).ttype, "acc") + : new Tupple(AMsymbols.get(i).tex, AMsymbols.get(i).tag, AMsymbols.get(i).output, null, + AMsymbols.get(i).ttype); + AMsymbols.add(tmp); + } + } + refreshSymbols(); + + } + + private static void refreshSymbols() { + Collections.sort(AMsymbols, new Comparator() { + public int compare(Tupple o1, Tupple o2) { + return o1.input.compareTo(o2.input); + } + }); + AMnames = new String[AMsymbols.size()]; + for (int i = 0; i < AMsymbols.size(); i++) + AMnames[i] = AMsymbols.get(i).input; + + } + + private String AMremoveCharsAndBlanks(String str, int n) { + // remove n characters and any following blanks + String st; + if (str.length() > n && str.charAt(n) == '\\' && str.charAt(n + 1) != '\\' && str.charAt(n + 1) != ' ') + st = slice(str, n + 1); + else + st = slice(str, n); + int i; + for (i = 0; i < st.length() && st.charAt(i) <= 32; i = i + 1) + ; + return slice(st, i); + } + + private int AMposition(String[] arr, String str, int n) { + // return position >=n where str appears or would be inserted + // assumes arr is sorted + int i = 0; + if (n == 0) { + int h, m; + n = -1; + h = arr.length; + while (n + 1 < h) { + m = (n + h) >> 1; + if (arr[m].compareTo(str) < 0) + n = m; + else + h = m; + } + return h; + } else { + for (i = n; i < arr.length && arr[i].compareTo(str) < 0; i++) + ; + } + return i; // i=arr.length || arr[i]>=str + } + + private Tupple AMgetSymbol(String str) { + // return maximal initial substring of str that appears in names + // return null if there is none + int k = 0; // new pos + int j = 0; // old pos + int mk = 0; // match pos + String st; + String tagst; + String match = ""; + boolean more = true; + for (int i = 1; i <= str.length() && more; i++) { + st = str.substring(0, i); // initial substring of length i + j = k; + k = AMposition(AMnames, st, j); + if (k < AMnames.length && slice(str, 0, AMnames[k].length()).equals(AMnames[k])) { + match = AMnames[k]; + mk = k; + i = match.length(); + } + more = k < AMnames.length && slice(str, 0, AMnames[k].length()).compareTo(AMnames[k]) >= 0; + } + AMpreviousSymbol = AMcurrentSymbol; + if (match.equals("") == false) { + AMcurrentSymbol = AMsymbols.get(mk).ttype; + return AMsymbols.get(mk); + } + // if str[0] is a digit or - return maxsubstring of digits.digits + AMcurrentSymbol = CONST; + k = 1; + st = slice(str, 0, 1); + boolean integ = true; + + while ("0".compareTo(st) <= 0 && st.compareTo("9") <= 0 && k <= str.length()) { + st = slice(str, k, k + 1); + k++; + } + + if (st.equals(".")) { + st = slice(str, k, k + 1); + if ("0".compareTo(st) <= 0 && st.compareTo("9") <= 0) { + integ = false; + k++; + while ("0".compareTo(st) <= 0 && st.compareTo("9") <= 0 && k <= str.length()) { + st = slice(str, k, k + 1); + k++; + } + } + } + if ((integ && k > 1) || k > 2) { + st = slice(str, 0, k - 1); + tagst = "mn"; + } else { + k = 2; + st = slice(str, 0, 1); // take 1 character + tagst = (("A".compareTo(st) > 0 || st.compareTo("Z") > 0) + && ("a".compareTo(st) > 0 || st.compareTo("z") > 0) ? "mo" : "mi"); + } + if (st.equals("-") && AMpreviousSymbol == INFIX) { + AMcurrentSymbol = INFIX; + return new Tupple(st, tagst, st, null, UNARY, "func", "val"); + } + return new Tupple(st, tagst, st, null, CONST, "val"); // added val bit + + } + + private String AMTremoveBrackets(String node) { + String st; + if (node.charAt(0) == '{' && node.charAt(node.length() - 1) == '}') { + int leftchop = 0; + + st = substr(node, 1, 5); + if (st.equals("\\left")) { + st = "" + node.charAt(6); + if (st.equals("(") || st.equals("[") || st.equals("{")) { + leftchop = 7; + } else { + st = substr(node, 6, 7); + if (st.equals("\\lbrace")) { + leftchop = 13; + } + } + } else { + st = "" + node.charAt(1); + if (st.equals("(") || st.equals("[")) { + leftchop = 2; + } + } + if (leftchop > 0) { + st = node.substring(node.length() - 8); + if (st.equals("\\right)}") || st.equals("\\right]}") || st.equals("\\right.}")) { + node = "{" + node.substring(leftchop); + node = node.substring(0, node.length() - 8) + "}"; + } else if (st.equals("\\rbrace}")) { + node = "{" + node.substring(leftchop); + node = node.substring(0, node.length() - 14) + "}"; + } + } + } + return node; + } + + private String AMTgetTeXsymbol(Tupple symb) { + String pre; + if (symb.hasFlag("val")) { + pre = ""; + } else { + pre = "\\"; + } + if (symb.tex == null) { + // can't remember why this was here. Breaks /delta /Delta to removed + // return (pre+(pre==''?symb.input:symb.input.toLowerCase())); + return (pre + symb.input); + } else { + return (pre + symb.tex); + } + } + + private String[] AMTparseSexpr(String str) { + Tupple symbol; + int i; + String node, st; + String newFrag = ""; + String result[]; + str = AMremoveCharsAndBlanks(str, 0); + symbol = AMgetSymbol(str); // either a token or a bracket or empty + if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) { + return new String[] { null, str }; + } + if (symbol.ttype == DEFINITION) { + str = symbol.output + AMremoveCharsAndBlanks(str, symbol.input.length()); + symbol = AMgetSymbol(str); + } + switch (symbol.ttype) { + case UNDEROVER: + case CONST: + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + String texsymbol = AMTgetTeXsymbol(symbol); + if (texsymbol.charAt(0) == '\\' || symbol.tag.equals("mo")) + return new String[] { texsymbol, str }; + else { + return new String[] { "{" + texsymbol + "}", str }; + } + + case LEFTBRACKET: // read (expr+) + AMnestingDepth++; + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + + result = AMTparseExpr(str, true); + AMnestingDepth--; + int leftchop = 0; + if (substr(result[0], 0, 6).equals("\\right")) { + st = "" + result[0].charAt(6); + if (st.equals(")") || st.equals("]") || st.equals("}")) { + leftchop = 6; + } else if (st == ".") { + leftchop = 7; + } else { + st = substr(result[0], 6, 7); + if (st.equals("\\rbrace")) { + leftchop = 13; + } + } + } + if (leftchop > 0) { + result[0] = result[0].substring(leftchop); + if (symbol.hasFlag("invisible")) + node = "{" + result[0] + "}"; + else { + node = "{" + AMTgetTeXsymbol(symbol) + result[0] + "}"; + } + } else { + if (symbol.hasFlag("invisible")) + node = "{\\left." + result[0] + "}"; + else { + node = "{\\left" + AMTgetTeXsymbol(symbol) + result[0] + "}"; + } + } + return new String[] { node, result[1] }; + + case TEXT: + if (symbol != AMquote) + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + if (str.charAt(0) == '{') + i = str.indexOf("}"); + else if (str.charAt(0) == '(') + i = str.indexOf(")"); + else if (str.charAt(0) == '[') + i = str.indexOf("]"); + else if (symbol == AMquote) + i = str.substring(1).indexOf("\"") + 1; + else + i = 0; + if (i == -1) + i = str.length(); + st = str.substring(1, i); + if (st.charAt(0) == ' ') { + newFrag = "\\ "; + } + newFrag += "\\text{" + st + "}"; + if (st.charAt(st.length() - 1) == ' ') { + newFrag += "\\ "; + } + str = AMremoveCharsAndBlanks(str, i + 1); + return new String[] { newFrag, str }; + + case UNARY: + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + result = AMTparseSexpr(str); + if (result[0] == null) + return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str }; + if (symbol.hasFlag("func")) { // functions hack + st = "" + str.charAt(0); + if (st.equals("^") || st.equals("_") || st.equals("/") || st.equals("|") || st.equals(",") + || (symbol.input.length() == 1 && symbol.input.matches("\\w") && !st.equals("("))) { + return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str }; + } else { + node = "{" + AMTgetTeXsymbol(symbol) + "{" + result[0] + "}}"; + return new String[] { node, result[1] }; + } + } + result[0] = AMTremoveBrackets(result[0]); + if (symbol.input.equals("sqrt")) { // sqrt + return new String[] { "\\sqrt{" + result[0] + "}", result[1] }; + } else if (symbol.input.equals("cancel")) { // cancel + return new String[] { "\\cancel{" + result[0] + "}", result[1] }; + } else if (symbol.rewriteleftright != null) { // abs, floor, ceil + return new String[] { "{\\left" + symbol.rewriteleftright[0] + result[0] + "\\right" + + symbol.rewriteleftright[1] + '}', result[1] }; + } else if (symbol.hasFlag("acc")) { // accent + return new String[] { AMTgetTeXsymbol(symbol) + "{" + result[0] + "}", result[1] }; + } else { // font change command + return new String[] { "{" + AMTgetTeXsymbol(symbol) + "{" + result[0] + "}}", result[1] }; + } + case BINARY: + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + result = AMTparseSexpr(str); + if (result[0] == null) + return new String[] { '{' + AMTgetTeXsymbol(symbol) + '}', str }; + result[0] = AMTremoveBrackets(result[0]); + String[] result2 = AMTparseSexpr(result[1]); + if (result2[0] == null) + return new String[] { '{' + AMTgetTeXsymbol(symbol) + '}', str }; + result2[0] = AMTremoveBrackets(result2[0]); + if (symbol.input.equals("color")) { + newFrag = "{\\color{" + result[0].replaceAll("[\\{\\}]", "") + "}" + result2[0] + "}"; + } else if (symbol.input.equals("root")) { + newFrag = "{\\sqrt[" + result[0] + "]{" + result2[0] + "}}"; + } else { + newFrag = "{" + AMTgetTeXsymbol(symbol) + "{" + result[0] + "}{" + result2[0] + "}}"; + } + return new String[] { newFrag, result2[1] }; + case INFIX: + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + return new String[] { symbol.output, str }; + case SPACE: + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + return new String[] { "{\\quad\\text{" + symbol.input + "}\\quad}", str }; + case LEFTRIGHT: + AMnestingDepth++; + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + result = AMTparseExpr(str, false); + AMnestingDepth--; + st = "" + result[0].charAt(result[0].length() - 1); + if (st.equals("|")) { // its an absolute value subterm + node = "{\\left|" + result[0] + "}"; + return new String[] { node, result[1] }; + } else { // the "|" is a \mid + node = "{\\mid}"; + return new String[] { node, str }; + } + default: + // alert("default"); + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str }; + + } + } + + private String[] AMTparseIexpr(String str) { + Tupple symbol, sym1, sym2; + String result[]; + String node; + str = AMremoveCharsAndBlanks(str, 0); + sym1 = AMgetSymbol(str); + result = AMTparseSexpr(str); + node = result[0]; + str = result[1]; + symbol = AMgetSymbol(str); + if (symbol.ttype == INFIX && !symbol.input.equals("/")) { + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + result = AMTparseSexpr(str); + if (result[0] == null) // show box in place of missing argument + result[0] = "{}"; + else + result[0] = AMTremoveBrackets(result[0]); + str = result[1]; + if (symbol.input.equals("_")) { + sym2 = AMgetSymbol(str); + if (sym2.input.equals("^")) { + str = AMremoveCharsAndBlanks(str, sym2.input.length()); + String[] res2 = AMTparseSexpr(str); + res2[0] = AMTremoveBrackets(res2[0]); + str = res2[1]; + node = "{" + node; + node += "_{" + result[0] + "}"; + node += "^{" + res2[0] + "}"; + node += "}"; + } else { + node += "_{" + result[0] + "}"; + } + } else { // must be ^ + node = node + "^{" + result[0] + "}"; + } + if (sym1.hasFlag("func")) { + sym2 = AMgetSymbol(str); + if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) { + result = AMTparseIexpr(str); + node = "{" + node + result[0] + "}"; + str = result[1]; + } + } + } + return new String[] { node, str }; + } + + private String[] AMTparseExpr(String str, boolean rightbracket) { + String result[]; + Tupple symbol; + String node; + // var symbol, node, result, i, nodeList = [], + String newFrag = ""; + boolean addedright = false; + do { + str = AMremoveCharsAndBlanks(str, 0); + result = AMTparseIexpr(str); + node = result[0]; + str = result[1]; + symbol = AMgetSymbol(str); + + if (symbol.ttype == INFIX && symbol.input.equals("/")) { + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + result = AMTparseIexpr(str); + + if (result[0] == null) // show box in place of missing argument + result[0] = "{}"; + else + result[0] = AMTremoveBrackets(result[0]); + str = result[1]; + node = AMTremoveBrackets(node); + node = "\\frac" + "{" + node + "}"; + node += "{" + result[0] + "}"; + newFrag += node; + symbol = AMgetSymbol(str); + } else if (node != null) + newFrag += node; + + } while ((((symbol.ttype != RIGHTBRACKET) && (symbol.ttype != LEFTRIGHT || rightbracket)) + || AMnestingDepth == 0) && (symbol.output == null || symbol.output.equals("") == false)); + + if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) { + int len = newFrag.length(); + if (len > 2 && newFrag.charAt(0) == '{' && newFrag.indexOf(',') > 0) { + char right = newFrag.charAt(len - 2); + if (right == ')' || right == ']') { + char left = newFrag.charAt(6); + if ((left == '(' && right == ')' && !symbol.output.equals("}")) || (left == '[' && right == ']')) { + String mxout = "\\begin{matrix}"; + List pos = new ArrayList<>(); // position of commas + pos.add(0); + boolean matrix = true; + int mxnestingd = 0; + List> subpos = new ArrayList<>(); + subpos.add(new ArrayList<>(Arrays.asList(0))); + int lastsubposstart = 0; + int mxanynestingd = 0; + + for (int i = 1; i < len - 1; i++) { + if (newFrag.charAt(i) == left) + mxnestingd++; + if (newFrag.charAt(i) == right) { + mxnestingd--; + if (mxnestingd == 0 && i + 3 < newFrag.length() && newFrag.charAt(i + 2) == ',' + && newFrag.charAt(i + 3) == '{') { + pos.add(i + 2); + lastsubposstart = i + 2; + while (subpos.size() <= lastsubposstart) + subpos.add(null); + subpos.set(lastsubposstart, new ArrayList<>(Arrays.asList(i + 2))); + } + } + if (newFrag.charAt(i) == '[' || newFrag.charAt(i) == '(' || newFrag.charAt(i) == '{') { + mxanynestingd++; + } + if (newFrag.charAt(i) == ']' || newFrag.charAt(i) == ')' || newFrag.charAt(i) == '}') { + mxanynestingd--; + } + if (newFrag.charAt(i) == ',' && mxanynestingd == 1) { + subpos.get(lastsubposstart).add(i); + } + if (mxanynestingd < 0) { // happens at the end of the row + if (lastsubposstart == i + 1) { // if at end of row, skip to next row + i++; + } else { // misformed something - abandon treating as a matrix + matrix = false; + } + } + } + + pos.add(len); + int lastmxsubcnt = -1; + if (mxnestingd == 0 && pos.size() > 0 && matrix) { + for (int i = 0; i < pos.size() - 1; i++) { + List subarr = null; + if (i > 0) + mxout += "\\\\"; + if (i == 0) { + // var subarr = newFrag.substr(pos[i]+7,pos[i+1]-pos[i]-15).split(','); + if (subpos.get(pos.get(i)).size() == 1) { + subarr = new ArrayList(Arrays.asList( + substr(newFrag, pos.get(i) + 7, pos.get(i + 1) - pos.get(i) - 15))); + } else { + subarr = new ArrayList(Arrays.asList( + newFrag.substring(pos.get(i) + 7, subpos.get(pos.get(i)).get(1)))); + for (int j = 2; j < subpos.get(pos.get(i)).size(); j++) { + subarr.add(newFrag.substring(subpos.get(pos.get(i)).get(j - 1) + 1, + subpos.get(pos.get(i)).get(j))); + } + subarr.add(newFrag.substring( + subpos.get(pos.get(i)).get(subpos.get(pos.get(i)).size() - 1) + 1, + pos.get(i + 1) - 8)); + } + } else { + // var subarr = newFrag.substr(pos[i]+8,pos[i+1]-pos[i]-16).split(','); + if (subpos.get(pos.get(i)).size() == 1) { + subarr = new ArrayList(Arrays.asList( + substr(newFrag, pos.get(i) + 8, pos.get(i + 1) - pos.get(i) - 16))); + } else { + subarr = new ArrayList(Arrays.asList( + newFrag.substring(pos.get(i) + 8, subpos.get(pos.get(i)).get(1)))); + for (int j = 2; j < subpos.get(pos.get(i)).size(); j++) { + subarr.add(newFrag.substring(subpos.get(i).get(j - 1) + 1, + subpos.get(i).get(j))); + } + subarr.add(newFrag.substring( + subpos.get(pos.get(i)).get(subpos.get(pos.get(i)).size() - 1) + 1, + pos.get(i + 1) - 8)); + } + } + if (lastmxsubcnt > 0 && subarr.size() != lastmxsubcnt) { + matrix = false; + } else if (lastmxsubcnt == -1) { + lastmxsubcnt = subarr.size(); + } + // mxout += subarr.join('&'); + for (int z = 0; z < subarr.size(); z++) { + mxout += subarr.get(z); + if (z < subarr.size() - 1) + mxout += "&"; + } + } + } + mxout += "\\end{matrix}"; + + if (matrix) { + newFrag = mxout; + } + + } + } + } + str = AMremoveCharsAndBlanks(str, symbol.input.length()); + if (!symbol.hasFlag("invisible")) { + node = "\\right" + AMTgetTeXsymbol(symbol); + newFrag += node; + addedright = true; + } else { + newFrag += "\\right."; + addedright = true; + } + } + if (AMnestingDepth > 0 && !addedright) { + newFrag += "\\right."; // adjust for non-matching left brackets + // todo: adjust for non-matching right brackets + } + + return new String[] { newFrag, str }; + } + + private String patchColor(String latex) { + return latex.replace("\\color{", "\\textcolor{"); + } + + public String getTeX(String asciiMathInput) { + AMnestingDepth = 0; + AMpreviousSymbol = 0; + AMcurrentSymbol = 0; + final String result = AMTparseExpr(asciiMathInput, false)[0]; + return patchColor(result); + } + + static { + AMinitSymbols(); + } + +} diff --git a/src/net/sourceforge/plantuml/math/AsciiMath.java b/src/net/sourceforge/plantuml/math/AsciiMath.java index 8887ea1a4..1614ae21d 100644 --- a/src/net/sourceforge/plantuml/math/AsciiMath.java +++ b/src/net/sourceforge/plantuml/math/AsciiMath.java @@ -37,59 +37,24 @@ package net.sourceforge.plantuml.math; import java.awt.Color; import java.awt.geom.Dimension2D; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; -import javax.script.Invocable; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; import javax.script.ScriptException; -import net.sourceforge.plantuml.BackSlash; import net.sourceforge.plantuml.ugraphic.MutableImage; import net.sourceforge.plantuml.ugraphic.UImageSvg; public class AsciiMath implements ScientificEquation { - private static final String ASCIIMATH_PARSER_JS_LOCATION = "/net/sourceforge/plantuml/math/"; - - private static String JAVASCRIPT_CODE; - private final LatexBuilder builder; private final String tex; - static { - try { - final BufferedReader br = new BufferedReader(new InputStreamReader( - AsciiMath.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "ASCIIMathTeXImg.js"), "UTF-8")); - final StringBuilder sb = new StringBuilder(); - String s = null; - while ((s = br.readLine()) != null) { - sb.append(s); - sb.append(BackSlash.NEWLINE); - } - br.close(); - JAVASCRIPT_CODE = sb.toString(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - public AsciiMath(String form) throws ScriptException, NoSuchMethodException { - final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); - engine.eval(JAVASCRIPT_CODE); - final Invocable inv = (Invocable) engine; - this.tex = patchColor((String) inv.invokeFunction("plantuml", form)); + this.tex = new ASCIIMathTeXImg().getTeX(form); this.builder = new LatexBuilder(tex); } - private String patchColor(String latex) { - return latex.replace("\\color{", "\\textcolor{"); - } - public Dimension2D getDimension() { return builder.getDimension(); } diff --git a/src/net/sourceforge/plantuml/math/AsciiMathJs.java b/src/net/sourceforge/plantuml/math/AsciiMathJs.java new file mode 100644 index 000000000..62e6a8a9b --- /dev/null +++ b/src/net/sourceforge/plantuml/math/AsciiMathJs.java @@ -0,0 +1,113 @@ +/* ======================================================================== + * 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.math; + +import java.awt.Color; +import java.awt.geom.Dimension2D; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.InvocationTargetException; + +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +import net.sourceforge.plantuml.BackSlash; +import net.sourceforge.plantuml.ugraphic.MutableImage; +import net.sourceforge.plantuml.ugraphic.UImageSvg; + +public class AsciiMathJs implements ScientificEquation { + + private static final String ASCIIMATH_PARSER_JS_LOCATION = "/net/sourceforge/plantuml/math/"; + + private static String JAVASCRIPT_CODE; + + private final LatexBuilder builder; + private final String tex; + + static { + try { + final BufferedReader br = new BufferedReader(new InputStreamReader( + AsciiMathJs.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "ASCIIMathTeXImg.js"), "UTF-8")); + final StringBuilder sb = new StringBuilder(); + String s = null; + while ((s = br.readLine()) != null) { + sb.append(s); + sb.append(BackSlash.NEWLINE); + } + br.close(); + JAVASCRIPT_CODE = sb.toString(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public AsciiMathJs(String form) throws ScriptException, NoSuchMethodException { + final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); + engine.eval(JAVASCRIPT_CODE); + final Invocable inv = (Invocable) engine; + this.tex = patchColor((String) inv.invokeFunction("plantuml", form)); + this.builder = new LatexBuilder(tex); + } + + private String patchColor(String latex) { + return latex.replace("\\color{", "\\textcolor{"); + } + + public Dimension2D getDimension() { + return builder.getDimension(); + } + + public UImageSvg getSvg(double scale, Color foregroundColor, Color backgroundColor) + throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, + NoSuchMethodException, SecurityException, InstantiationException, IOException { + return builder.getSvg(scale, foregroundColor, backgroundColor); + } + + public MutableImage getImage(Color foregroundColor, Color backgroundColor) + throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException { + return builder.getImage(foregroundColor, backgroundColor); + } + + public String getSource() { + return tex; + } + +} diff --git a/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java b/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java index 2d624c200..d8694fa04 100644 --- a/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java +++ b/src/net/sourceforge/plantuml/math/ScientificEquationSafe.java @@ -35,6 +35,9 @@ */ package net.sourceforge.plantuml.math; +import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainImageBuilder; +import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainPngBuilder; + import java.awt.Color; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -57,9 +60,6 @@ import net.sourceforge.plantuml.ugraphic.MutableImage; import net.sourceforge.plantuml.ugraphic.PixelImage; import net.sourceforge.plantuml.ugraphic.UImageSvg; -import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainImageBuilder; -import static net.sourceforge.plantuml.ugraphic.ImageBuilder.plainPngBuilder; - public class ScientificEquationSafe { private final ScientificEquation equation; diff --git a/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java b/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java index 6f4b048c8..15214ac2c 100644 --- a/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java +++ b/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java @@ -43,6 +43,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -63,6 +64,11 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.nwdiag.legacy.GridTextBlockDecorated; +import net.sourceforge.plantuml.nwdiag.legacy.NServerLegacy; +import net.sourceforge.plantuml.nwdiag.legacy.NetworkLegacy; +import net.sourceforge.plantuml.nwdiag.legacy.NwGroupLegacy; +import net.sourceforge.plantuml.nwdiag.next.NPlayField; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.ugraphic.MinMax; @@ -76,10 +82,12 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils; public class NwDiagram extends UmlDiagram { private boolean initDone; - private final Map squares = new LinkedHashMap(); - private final List networks = new ArrayList<>(); - private final List groups = new ArrayList<>(); - private NwGroup currentGroup = null; + private final Map servers = new LinkedHashMap(); + private final List networks = new ArrayList<>(); + private final List groups = new ArrayList<>(); + private NwGroupLegacy currentGroup = null; + + private final NPlayField playField = new NPlayField(); public DiagramDescription getDescription() { return new DiagramDescription("(Nwdiag)"); @@ -93,7 +101,7 @@ public class NwDiagram extends UmlDiagram { initDone = true; } - private Network currentNetwork() { + private NetworkLegacy currentNetwork() { if (networks.size() == 0) { return null; } @@ -104,7 +112,7 @@ public class NwDiagram extends UmlDiagram { if (initDone == false) { return errorNoInit(); } - currentGroup = new NwGroup(name, currentNetwork()); + currentGroup = new NwGroupLegacy(name, currentNetwork()); groups.add(currentGroup); return CommandExecutionResult.ok(); } @@ -117,8 +125,8 @@ public class NwDiagram extends UmlDiagram { return CommandExecutionResult.ok(); } - private Network createNetwork(String name) { - final Network network = new Network(name, networks.size()); + private NetworkLegacy createNetwork(String name) { + final NetworkLegacy network = new NetworkLegacy(playField.createNewStage(), name, networks.size()); networks.add(network); return network; } @@ -127,46 +135,37 @@ public class NwDiagram extends UmlDiagram { if (initDone == false) { return errorNoInit(); } + final NServerLegacy element; if (currentNetwork() == null) { createNetwork(name1); - addSquare(null, name2, toSet(null)); - return CommandExecutionResult.ok(); + element = new NServerLegacy(name2, currentNetwork(), this.getSkinParam()); } else { - final Square already = squares.get(name1); - final Network network1 = createNetwork(""); + final NServerLegacy already = servers.get(name1); + final NetworkLegacy network1 = createNetwork(""); network1.goInvisible(); if (already != null) { - currentNetwork().addSquare(already, toSet(null)); + currentNetwork().addServer(already, toSet(null)); + already.connect(currentNetwork(), toSet(null)); } - final Square added = addSquare(null, name2, toSet(null)); - added.sameColThan(already); - return CommandExecutionResult.ok(); + element = new NServerLegacy(name2, currentNetwork(), this.getSkinParam()); + element.sameColThan(already); } + servers.put(name2, element); + addInternal(element, toSet(null)); + return CommandExecutionResult.ok(); } - private Square addSquare(Square element, String name, Map props) { - if (element == null) { - element = new Square(name, currentNetwork(), this.getSkinParam()); - squares.put(name, element); - } - currentNetwork().addSquare(element, props); + private void addInternal(NServerLegacy server, Map props) { + currentNetwork().addServer(Objects.requireNonNull(server), props); + server.connect(currentNetwork(), props); final String description = props.get("description"); if (description != null) { - element.setDescription(description); + server.setDescription(description); } final String shape = props.get("shape"); if (shape != null) { - element.setShape(shape); + server.setShape(shape); } - return element; - } - - public CommandExecutionResult endSomething() { - if (initDone == false) { - return errorNoInit(); - } - this.currentGroup = null; - return CommandExecutionResult.ok(); } public CommandExecutionResult addElement(String name, String definition) { @@ -174,19 +173,35 @@ public class NwDiagram extends UmlDiagram { return errorNoInit(); } if (currentGroup != null) { - currentGroup.addElement(name); + currentGroup.addName(name); } + NServerLegacy server = null; if (currentNetwork() == null) { - if (currentGroup == null) { - final Network network1 = createNetwork(""); - network1.goInvisible(); - final Square first = addSquare(null, name, toSet(definition)); - first.doNotHaveItsOwnColumn(); + if (currentGroup != null) { + return CommandExecutionResult.ok(); } + assert currentGroup == null; + final NetworkLegacy network1 = createNetwork(""); + network1.goInvisible(); + server = new NServerLegacy(name, currentNetwork(), this.getSkinParam()); + servers.put(name, server); + server.doNotHaveItsOwnColumn(); } else { - final Square element = squares.get(name); - addSquare(element, name, toSet(definition)); + server = servers.get(name); + if (server == null) { + server = new NServerLegacy(name, currentNetwork(), this.getSkinParam()); + servers.put(name, server); + } } + addInternal(server, toSet(definition)); + return CommandExecutionResult.ok(); + } + + public CommandExecutionResult endSomething() { + if (initDone == false) { + return errorNoInit(); + } + this.currentGroup = null; return CommandExecutionResult.ok(); } @@ -274,7 +289,7 @@ public class NwDiagram extends UmlDiagram { double deltaX = 0; double deltaY = 0; for (int i = 0; i < networks.size(); i++) { - final Network current = networks.get(i); + final NetworkLegacy current = networks.get(i); final String address = current.getOwnAdress(); final TextBlock desc = toTextBlock(current.getName(), address); final Dimension2D dim = desc.calculateDimension(stringBounder); @@ -285,7 +300,7 @@ public class NwDiagram extends UmlDiagram { } double y = 0; for (int i = 0; i < networks.size(); i++) { - final Network current = networks.get(i); + final NetworkLegacy current = networks.get(i); final String address = current.getOwnAdress(); final TextBlock desc = toTextBlock(current.getName(), address); final Dimension2D dim = desc.calculateDimension(stringBounder); @@ -304,9 +319,9 @@ public class NwDiagram extends UmlDiagram { } - private Map getLinks(Square element) { - final Map result = new LinkedHashMap(); - for (Network network : networks) { + private Map getLinks(NServerLegacy element) { + final Map result = new LinkedHashMap(); + for (NetworkLegacy network : networks) { final String s = network.getAdress(element); if (s != null) { result.put(network, s); @@ -316,17 +331,17 @@ public class NwDiagram extends UmlDiagram { } private GridTextBlockDecorated buildGrid() { - final GridTextBlockDecorated grid = new GridTextBlockDecorated(networks.size(), squares.size(), groups, + final GridTextBlockDecorated grid = new GridTextBlockDecorated(networks.size(), servers.size(), groups, networks, getSkinParam()); for (int i = 0; i < networks.size(); i++) { - final Network current = networks.get(i); + final NetworkLegacy current = networks.get(i); int j = 0; - for (Map.Entry ent : squares.entrySet()) { - final Square square = ent.getValue(); + for (Map.Entry ent : servers.entrySet()) { + final NServerLegacy square = ent.getValue(); if (square.getMainNetwork() == current) { - final Map conns = getLinks(square); - final Square sameCol = square.getSameCol(); + final Map conns = getLinks(square); + final NServerLegacy sameCol = square.getSameCol(); if (sameCol != null) { square.setNumCol(sameCol.getNumCol()); } else { @@ -357,7 +372,7 @@ public class NwDiagram extends UmlDiagram { } if ("color".equalsIgnoreCase(property)) { final HColor color = value == null ? null - : NwGroup.colors.getColorOrWhite(getSkinParam().getThemeStyle(), value); + : NwGroupLegacy.colors.getColorOrWhite(getSkinParam().getThemeStyle(), value); if (currentGroup != null) { currentGroup.setColor(color); } else if (currentNetwork() != null) { diff --git a/src/net/sourceforge/plantuml/nwdiag/core/NServer.java b/src/net/sourceforge/plantuml/nwdiag/core/NServer.java new file mode 100644 index 000000000..d310f9a36 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/core/NServer.java @@ -0,0 +1,113 @@ +/* ======================================================================== + * 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.nwdiag.core; + +import java.util.LinkedHashMap; +import java.util.Map; + +import net.sourceforge.plantuml.ComponentStyle; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.USymbol; +import net.sourceforge.plantuml.nwdiag.next.NBar; +import net.sourceforge.plantuml.skin.ActorStyle; +import net.sourceforge.plantuml.svek.PackageStyle; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.color.HColorUtils; + +public class NServer { + + private final Map connections = new LinkedHashMap(); + + private USymbol shape = USymbol.RECTANGLE; + private final String name; + private String description; + private final NBar bar = new NBar(); + + public void connect(Network network, Map props) { + String address = props.get("address"); + if (address == null) { + address = ""; + } + if (address.length() == 0 && connections.containsKey(network)) { + return; + } + connections.put(network, address); + bar.addStage(network.getNstage()); + } + + @Override + public final String toString() { + return name; + } + + public NServer(String name) { + this.description = name; + this.name = name; + } + + protected final FontConfiguration getFontConfiguration() { + final UFont font = UFont.serif(11); + return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false); + } + + public final String getDescription() { + return description; + } + + public final void setDescription(String description) { + this.description = description; + } + + public final String getName() { + return name; + } + + public final void setShape(String shapeName) { + final USymbol shapeFromString = USymbol.fromString(shapeName, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE, + PackageStyle.RECTANGLE); + if (shapeFromString != null) { + this.shape = shapeFromString; + } + } + + public final USymbol getShape() { + return shape; + } + + public final NBar getBar() { + return bar; + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/Network.java b/src/net/sourceforge/plantuml/nwdiag/core/Network.java similarity index 65% rename from src/net/sourceforge/plantuml/nwdiag/Network.java rename to src/net/sourceforge/plantuml/nwdiag/core/Network.java index 9db712d3e..a9bf3b55c 100644 --- a/src/net/sourceforge/plantuml/nwdiag/Network.java +++ b/src/net/sourceforge/plantuml/nwdiag/core/Network.java @@ -32,55 +32,29 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; - -import java.util.LinkedHashMap; -import java.util.Map; +package net.sourceforge.plantuml.nwdiag.core; +import net.sourceforge.plantuml.nwdiag.next.NStage; import net.sourceforge.plantuml.ugraphic.color.HColor; public class Network { private final String name; - private final Map localSquare = new LinkedHashMap(); private HColor color; private boolean visible = true; private String ownAdress; + private double y; private boolean fullWidth; - private final int stage; + private final NStage nstage; @Override public String toString() { - return name + "(" + stage + ")"; + return name; } - public Network(String name, int stage) { + public Network(NStage nstage, String name) { this.name = name; - this.stage = stage; - } - - public String getAdress(Square element) { - return localSquare.get(element); - } - - public void addSquare(Square square, Map props) { - String address = props.get("address"); - if (address == null) { - address = ""; - } - if (address.length() == 0 && localSquare.containsKey(square)) { - return; - } - localSquare.put(square, address); - } - - public boolean constainsLocally(String name) { - for (Square square : localSquare.keySet()) { - if (square.getName().equals(name)) { - return true; - } - } - return false; + this.nstage = nstage; } public final String getOwnAdress() { @@ -103,7 +77,7 @@ public class Network { this.color = color; } - public void goInvisible() { + public final void goInvisible() { this.visible = false; } @@ -111,36 +85,6 @@ public class Network { return visible; } - public void setFullWidth(boolean fullWidth) { - this.fullWidth = fullWidth; - } - - public final boolean isFullWidth() { - return fullWidth; - } - - public final int getStage() { - return stage; - } - - private double xmin; - private double xmax; - private double y; - - public void setMinMax(double xmin, double xmax) { - this.xmin = xmin; - this.xmax = xmax; - - } - - public final double getXmin() { - return xmin; - } - - public final double getXmax() { - return xmax; - } - public final double getY() { return y; } @@ -149,4 +93,16 @@ public class Network { this.y = y; } + public void setFullWidth(boolean fullWidth) { + this.fullWidth = fullWidth; + } + + public final boolean isFullWidth() { + return fullWidth; + } + + public final NStage getNstage() { + return nstage; + } + } diff --git a/src/net/sourceforge/plantuml/nwdiag/core/NwGroup.java b/src/net/sourceforge/plantuml/nwdiag/core/NwGroup.java new file mode 100644 index 000000000..2cc00d8d5 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/core/NwGroup.java @@ -0,0 +1,116 @@ +/* ======================================================================== + * 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.nwdiag.core; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.nwdiag.legacy.NServerLegacy; +import net.sourceforge.plantuml.nwdiag.next.NBox; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.HColorSet; +import net.sourceforge.plantuml.ugraphic.color.HColorUtils; + +public class NwGroup { + + public static final HColorSet colors = HColorSet.instance(); + + private final Set names = new HashSet<>(); + + private final String name; + private HColor color; + private String description; + private NBox nbox; + + public final NBox getNbox(Map servers) { + if (nbox == null) { + nbox = new NBox(); + for (Entry ent : servers.entrySet()) { + if (names.contains(ent.getKey())) { + nbox.add(ent.getValue().getBar()); + } + } + } + return nbox; + } + + public void addName(String name) { + this.names.add(name); + } + + @Override + public String toString() { + return name; + } + + public NwGroup(String name) { + this.name = name; + } + + public final String getName() { + return name; + } + + public final HColor getColor() { + return color; + } + + public final void setColor(HColor color) { + this.color = color; + } + + public final void setDescription(String value) { + this.description = value; + } + + public final FontConfiguration getGroupDescriptionFontConfiguration() { + final UFont font = UFont.serif(11); + return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false); + } + + protected final String getDescription() { + return description; + } + + public final Set names() { + return Collections.unmodifiableSet(names); + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/Footprint.java b/src/net/sourceforge/plantuml/nwdiag/legacy/Footprint.java similarity index 97% rename from src/net/sourceforge/plantuml/nwdiag/Footprint.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/Footprint.java index 45d78a695..a17ab310e 100644 --- a/src/net/sourceforge/plantuml/nwdiag/Footprint.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/Footprint.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; public class Footprint { diff --git a/src/net/sourceforge/plantuml/nwdiag/GridTextBlockDecorated.java b/src/net/sourceforge/plantuml/nwdiag/legacy/GridTextBlockDecorated.java similarity index 89% rename from src/net/sourceforge/plantuml/nwdiag/GridTextBlockDecorated.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/GridTextBlockDecorated.java index 6dcb112c5..870da182f 100644 --- a/src/net/sourceforge/plantuml/nwdiag/GridTextBlockDecorated.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/GridTextBlockDecorated.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; import java.util.List; @@ -47,10 +47,10 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { public static final int NETWORK_THIN = 5; - private final List groups; - private final List networks; + private final List groups; + private final List networks; - public GridTextBlockDecorated(int lines, int cols, List groups, List networks, + public GridTextBlockDecorated(int lines, int cols, List groups, List networks, ISkinParam skinparam) { super(lines, cols, skinparam); this.groups = groups; @@ -59,7 +59,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { @Override protected void drawGrid(UGraphic ug) { - for (NwGroup group : groups) { + for (NwGroupLegacy group : groups) { drawGroups(ug, group, skinparam); } drawNetworkTube(ug); @@ -82,7 +82,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { } - private void drawGroups(UGraphic ug, NwGroup group, ISkinParam skinParam) { + private void drawGroups(UGraphic ug, NwGroupLegacy group, ISkinParam skinParam) { final StringBounder stringBounder = ug.getStringBounder(); MinMax size = null; @@ -108,7 +108,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { } - private boolean isThereALink(int j, Network network) { + private boolean isThereALink(int j, NetworkLegacy network) { for (int i = 0; i < data.getNbLines(); i++) { final LinkedElement element = data.get(i, j); if (element != null && element.isLinkedTo(network)) { @@ -123,7 +123,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { final StringBounder stringBounder = ug.getStringBounder(); double y = 0; for (int i = 0; i < data.getNbLines(); i++) { - final Network network = getNetwork(i); + final NetworkLegacy network = getNetwork(i); computeMixMax(data.getLine(i), stringBounder, network); final URectangle rect = new URectangle(network.getXmax() - network.getXmin(), NETWORK_THIN); @@ -142,7 +142,7 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { } } - private void computeMixMax(LinkedElement line[], StringBounder stringBounder, Network network) { + private void computeMixMax(LinkedElement line[], StringBounder stringBounder, NetworkLegacy network) { double x = 0; double xmin = network.isFullWidth() ? 0 : -1; double xmax = 0; @@ -160,15 +160,15 @@ public class GridTextBlockDecorated extends GridTextBlockSimple { } - private Network getNetwork(int i) { + private NetworkLegacy getNetwork(int i) { return networks.get(i); } public void checkGroups() { for (int i = 0; i < groups.size(); i++) { for (int j = i + 1; j < groups.size(); j++) { - final NwGroup group1 = groups.get(i); - final NwGroup group2 = groups.get(j); + final NwGroupLegacy group1 = groups.get(i); + final NwGroupLegacy group2 = groups.get(j); if (group1.size() == 0 || group2.size() == 0) { continue; } diff --git a/src/net/sourceforge/plantuml/nwdiag/GridTextBlockSimple.java b/src/net/sourceforge/plantuml/nwdiag/legacy/GridTextBlockSimple.java similarity index 97% rename from src/net/sourceforge/plantuml/nwdiag/GridTextBlockSimple.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/GridTextBlockSimple.java index 453e96490..80df3b93d 100644 --- a/src/net/sourceforge/plantuml/nwdiag/GridTextBlockSimple.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/GridTextBlockSimple.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; import java.awt.geom.Dimension2D; import java.awt.geom.Rectangle2D; @@ -124,7 +124,7 @@ public class GridTextBlockSimple implements TextBlock { data.set(i, j, value); } - public Footprint getFootprint(NwGroup group) { + public Footprint getFootprint(NwGroupLegacy group) { return data.getFootprint(group); } diff --git a/src/net/sourceforge/plantuml/nwdiag/LinkedElement.java b/src/net/sourceforge/plantuml/nwdiag/legacy/LinkedElement.java similarity index 90% rename from src/net/sourceforge/plantuml/nwdiag/LinkedElement.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/LinkedElement.java index 450c2625a..07b14f8c1 100644 --- a/src/net/sourceforge/plantuml/nwdiag/LinkedElement.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/LinkedElement.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; import java.awt.geom.Dimension2D; import java.util.Collections; @@ -45,6 +45,7 @@ import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.nwdiag.VerticalLine; import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -54,12 +55,12 @@ import net.sourceforge.plantuml.utils.MathUtils; public class LinkedElement { private final TextBlock box; - private final Network network; - private final Square square; - private final Map conns; - private final List networks; + private final NetworkLegacy network; + private final NServerLegacy square; + private final Map conns; + private final List networks; - public LinkedElement(Square square, TextBlock box, Map conns, List networks) { + public LinkedElement(NServerLegacy square, TextBlock box, Map conns, List networks) { this.networks = networks; this.box = box; this.network = square.getMainNetwork(); @@ -67,7 +68,7 @@ public class LinkedElement { this.conns = conns; } - public boolean isLinkedTo(Network some) { + public boolean isLinkedTo(NetworkLegacy some) { return conns.containsKey(some); } @@ -110,7 +111,7 @@ public class LinkedElement { final TreeSet skip = new TreeSet<>(); - for (Network n : networks) { + for (NetworkLegacy n : networks) { if (xstart + xMiddle > n.getXmin() && xstart + xMiddle < n.getXmax()) skip.add(n.getY()); } @@ -129,7 +130,7 @@ public class LinkedElement { final double seven = 7.0; double x = xMiddle - (conns.size() - 2) * seven / 2; boolean first = true; - for (Entry ent : conns.entrySet()) { + for (Entry ent : conns.entrySet()) { if (ent.getKey() == network) { continue; } @@ -183,11 +184,11 @@ public class LinkedElement { return new Dimension2DDouble(width, height); } - public final Network getNetwork() { + public final NetworkLegacy getNetwork() { return network; } - public final Square getElement() { + public final NServerLegacy getElement() { return square; } diff --git a/src/net/sourceforge/plantuml/nwdiag/Square.java b/src/net/sourceforge/plantuml/nwdiag/legacy/NServerLegacy.java similarity index 59% rename from src/net/sourceforge/plantuml/nwdiag/Square.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/NServerLegacy.java index c1e3d347d..5ffe9d792 100644 --- a/src/net/sourceforge/plantuml/nwdiag/Square.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/NServerLegacy.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; import java.util.LinkedHashMap; import java.util.List; @@ -40,39 +40,24 @@ import java.util.Map; import java.util.Map.Entry; import net.sourceforge.plantuml.ColorParam; -import net.sourceforge.plantuml.ComponentStyle; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.cucadiagram.Display; -import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.SymbolContext; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; -import net.sourceforge.plantuml.graphic.USymbol; -import net.sourceforge.plantuml.skin.ActorStyle; -import net.sourceforge.plantuml.svek.PackageStyle; -import net.sourceforge.plantuml.ugraphic.UFont; -import net.sourceforge.plantuml.ugraphic.color.HColorUtils; +import net.sourceforge.plantuml.nwdiag.core.NServer; -public class Square { +public class NServerLegacy extends NServer { - private USymbol shape = USymbol.RECTANGLE; - private final String name; - private String description; - private final Network mainNetwork; + private final NetworkLegacy mainNetwork; private final ISkinSimple spriteContainer; private boolean hasItsOwnColumn = true; - private Square sameCol; + private NServerLegacy sameCol; - @Override - public String toString() { - return name; - } - - public Square(String name, Network network, ISkinSimple spriteContainer) { - this.description = name; + public NServerLegacy(String name, NetworkLegacy network, ISkinSimple spriteContainer) { + super(name); this.mainNetwork = network; - this.name = name; this.spriteContainer = spriteContainer; } @@ -87,48 +72,23 @@ public class Square { return Display.getWithNewlines(s).create(getFontConfiguration(), HorizontalAlignment.LEFT, spriteContainer); } - private FontConfiguration getFontConfiguration() { - final UFont font = UFont.serif(11); - return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false); - } - - public LinkedElement asTextBlock(Map conns, List networks) { - final Map conns2 = new LinkedHashMap(); - for (Entry ent : conns.entrySet()) { + public LinkedElement asTextBlock(Map conns, List networks) { + final Map conns2 = new LinkedHashMap(); + for (Entry ent : conns.entrySet()) { conns2.put(ent.getKey(), toTextBlock(ent.getValue())); } final SymbolContext symbolContext = new SymbolContext(ColorParam.activityBackground.getDefaultValue(), ColorParam.activityBorder.getDefaultValue()).withShadow(3); - final TextBlock desc = toTextBlock(description); - final TextBlock box = shape.asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), symbolContext, - HorizontalAlignment.CENTER); + final TextBlock desc = toTextBlock(getDescription()); + final TextBlock box = getShape().asSmall(TextBlockUtils.empty(0, 0), desc, TextBlockUtils.empty(0, 0), + symbolContext, HorizontalAlignment.CENTER); return new LinkedElement(this, box, conns2, networks); } - public String getDescription() { - return description; - } - - public final Network getMainNetwork() { + public final NetworkLegacy getMainNetwork() { return mainNetwork; } - public void setDescription(String description) { - this.description = description; - } - - public String getName() { - return name; - } - - public final void setShape(String shapeName) { - final USymbol shapeFromString = USymbol.fromString(shapeName, ActorStyle.STICKMAN, ComponentStyle.RECTANGLE, - PackageStyle.RECTANGLE); - if (shapeFromString != null) { - this.shape = shapeFromString; - } - } - public void doNotHaveItsOwnColumn() { this.hasItsOwnColumn = false; } @@ -137,11 +97,11 @@ public class Square { return hasItsOwnColumn; } - public void sameColThan(Square sameCol) { + public void sameColThan(NServerLegacy sameCol) { this.sameCol = sameCol; } - public final Square getSameCol() { + public final NServerLegacy getSameCol() { return sameCol; } diff --git a/src/net/sourceforge/plantuml/nwdiag/legacy/NetworkLegacy.java b/src/net/sourceforge/plantuml/nwdiag/legacy/NetworkLegacy.java new file mode 100644 index 000000000..f200b68b3 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/NetworkLegacy.java @@ -0,0 +1,102 @@ +/* ======================================================================== + * 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.nwdiag.legacy; + +import java.util.LinkedHashMap; +import java.util.Map; + +import net.sourceforge.plantuml.nwdiag.core.Network; +import net.sourceforge.plantuml.nwdiag.next.NStage; + +public class NetworkLegacy extends Network { + + private final Map localServers = new LinkedHashMap(); + private final int stage; + + @Override + public String toString() { + return super.toString() + "(" + stage + ")"; + } + + public NetworkLegacy(NStage nstage, String name, int stage) { + super(nstage, name); + this.stage = stage; + } + + public String getAdress(NServerLegacy server) { + return localServers.get(server); + } + + public void addServer(NServerLegacy server, Map props) { + String address = props.get("address"); + if (address == null) { + address = ""; + } + if (address.length() == 0 && localServers.containsKey(server)) { + return; + } + localServers.put(server, address); + } + + public boolean constainsLocally(String name) { + for (NServerLegacy server : localServers.keySet()) { + if (server.getName().equals(name)) { + return true; + } + } + return false; + } + + public final int getStage() { + return stage; + } + + private double xmin; + private double xmax; + + public void setMinMax(double xmin, double xmax) { + this.xmin = xmin; + this.xmax = xmax; + } + + public final double getXmin() { + return xmin; + } + + public final double getXmax() { + return xmax; + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/NwArray.java b/src/net/sourceforge/plantuml/nwdiag/legacy/NwArray.java similarity index 95% rename from src/net/sourceforge/plantuml/nwdiag/NwArray.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/NwArray.java index d809f3dd5..d04f9435f 100644 --- a/src/net/sourceforge/plantuml/nwdiag/NwArray.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/NwArray.java @@ -32,7 +32,7 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; public class NwArray { @@ -74,7 +74,7 @@ public class NwArray { } - public Footprint getFootprint(NwGroup group) { + public Footprint getFootprint(NwGroupLegacy group) { int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int i = 0; i < getNbLines(); i++) { diff --git a/src/net/sourceforge/plantuml/nwdiag/NwGroup.java b/src/net/sourceforge/plantuml/nwdiag/legacy/NwGroupLegacy.java similarity index 63% rename from src/net/sourceforge/plantuml/nwdiag/NwGroup.java rename to src/net/sourceforge/plantuml/nwdiag/legacy/NwGroupLegacy.java index 4ceb142c6..a24b3dec4 100644 --- a/src/net/sourceforge/plantuml/nwdiag/NwGroup.java +++ b/src/net/sourceforge/plantuml/nwdiag/legacy/NwGroupLegacy.java @@ -32,81 +32,50 @@ * Original Author: Arnaud Roques * */ -package net.sourceforge.plantuml.nwdiag; +package net.sourceforge.plantuml.nwdiag.legacy; import java.awt.geom.Dimension2D; -import java.util.HashSet; -import java.util.Set; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.cucadiagram.Display; -import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.nwdiag.core.NwGroup; import net.sourceforge.plantuml.ugraphic.MinMax; -import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; -import net.sourceforge.plantuml.ugraphic.color.HColorSet; -import net.sourceforge.plantuml.ugraphic.color.HColorUtils; -public class NwGroup { +public class NwGroupLegacy extends NwGroup { - public static final HColorSet colors = HColorSet.instance(); - - private final String name; - private final Network network; - private final Set elements = new HashSet<>(); - private HColor color; - private String description; + private final NetworkLegacy network; @Override public String toString() { - return name + " " + network + " " + elements; + return getName() + " " + network + " " + names(); } - public NwGroup(String name, Network network) { - this.name = name; + public NwGroupLegacy(String name, NetworkLegacy network) { + super(name); this.network = network; } public int size() { - return elements.size(); - } - - public final String getName() { - return name; - } - - public void addElement(String name) { - this.elements.add(name); + return names().size(); } public boolean matches(LinkedElement tested) { if (network != null && network != tested.getNetwork()) { return false; } - return elements.contains(tested.getElement().getName()); - } - - public final HColor getColor() { - return color; - } - - public final void setColor(HColor color) { - this.color = color; - } - - public void setDescription(String value) { - this.description = value; + return names().contains(tested.getElement().getName()); } public void drawGroup(UGraphic ug, MinMax size, ISkinParam skinParam) { TextBlock block = null; Dimension2D blockDim = null; - if (description != null) { - block = Display.getWithNewlines(description).create(getGroupDescriptionFontConfiguration(), + if (getDescription() != null) { + block = Display.getWithNewlines(getDescription()).create(getGroupDescriptionFontConfiguration(), HorizontalAlignment.LEFT, skinParam); blockDim = block.calculateDimension(ug.getStringBounder()); final double dy = size.getMinY() - blockDim.getHeight(); @@ -123,12 +92,7 @@ public class NwGroup { } } - private FontConfiguration getGroupDescriptionFontConfiguration() { - final UFont font = UFont.serif(11); - return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false); - } - - public final Network getNetwork() { + public final NetworkLegacy getNetwork() { return network; } diff --git a/src/net/sourceforge/plantuml/nwdiag/next/BooleanGrid.java b/src/net/sourceforge/plantuml/nwdiag/next/BooleanGrid.java new file mode 100644 index 000000000..ea353f0f5 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/next/BooleanGrid.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.nwdiag.next; + +import java.util.HashSet; +import java.util.Set; + +public class BooleanGrid { + + private final Set burned = new HashSet<>(); + + private int merge(int x, int y) { + return x + (y << 16); + } + + public void burn(int x, int y) { + final boolean added = burned.add(merge(x, y)); + if (added == false) { + throw new IllegalArgumentException("Already present"); + } + } + + public boolean isBurned(int x, int y) { + return burned.contains(merge(x, y)); + } + + public void burnRect(int x1, int y1, int x2, int y2) { + check(x1, y1, x2, y2); + for (int x = x1; x <= x2; x++) + for (int y = y1; y <= y2; y++) + burn(x, y); + } + + public boolean isBurnRect(int x1, int y1, int x2, int y2) { + check(x1, y1, x2, y2); + for (int x = x1; x <= x2; x++) + for (int y = y1; y <= y2; y++) + if (isBurned(x, y)) + return true; + return false; + } + + private void check(int x1, int y1, int x2, int y2) { + if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0) { + throw new IllegalArgumentException(); + } + if (x2 < x1) { + throw new IllegalArgumentException(); + } + if (y2 < y1) { + throw new IllegalArgumentException(); + } + } + + // ----------------- + + public boolean isSpaceAvailable(Staged element, int x) { + if (isBurnRect(x, element.getStart().getNumber(), x + element.getNWidth() - 1, element.getEnd().getNumber())) { + return false; + } + return true; + } + + public void useSpace(Staged element, int x) { + burnRect(x, element.getStart().getNumber(), x + element.getNWidth() - 1, element.getEnd().getNumber()); + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/next/NBar.java b/src/net/sourceforge/plantuml/nwdiag/next/NBar.java new file mode 100644 index 000000000..af8934709 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/next/NBar.java @@ -0,0 +1,89 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.nwdiag.next; + +import java.util.Objects; + +public class NBar implements Staged { + + private NBox parent; + private NStage start; + private NStage end; + + @Override + public String toString() { + return start + "->" + end; + } + + public final NBox getParent() { + return parent; + } + + public final void setParent(NBox parent) { + this.parent = parent; + } + + @Override + public final NStage getStart() { + return start; + } + + @Override + public final NStage getEnd() { + return end; + } + + public void addStage(NStage stage) { + Objects.requireNonNull(stage); + if (start == null && end == null) { + this.start = stage; + this.end = stage; + } else { + this.start = NStage.getMin(this.start, stage); + this.end = NStage.getMax(this.end, stage); + } + } + + @Override + public int getNWidth() { + return 1; + } + + @Override + public boolean contains(NStage stage) { + return stage.compareTo(start) >= 0 && stage.compareTo(end) <= 0; + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/next/NBox.java b/src/net/sourceforge/plantuml/nwdiag/next/NBox.java new file mode 100644 index 000000000..0dc037345 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/next/NBox.java @@ -0,0 +1,89 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.nwdiag.next; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class NBox implements Staged { + + private final List bars = new ArrayList<>(); + private final NTetris tetris = new NTetris<>(); + + public void add(NBar bar) { + this.bars.add(bar); + this.tetris.add(bar); + } + +// public void addAll(NBox other) { +// for (NBar bar : other.bars) { +// add(bar); +// } +// } + + @Override + public NStage getStart() { + NStage result = bars.get(0).getStart(); + for (int i = 1; i < bars.size(); i++) { + result = NStage.getMin(result, bars.get(i).getStart()); + } + return result; + } + + @Override + public NStage getEnd() { + NStage result = bars.get(0).getEnd(); + for (int i = 1; i < bars.size(); i++) { + result = NStage.getMax(result, bars.get(i).getEnd()); + } + return result; + } + + @Override + public int getNWidth() { + return tetris.getNWidth(); + } + + public Map getPositions() { + return tetris.getPositions(); + } + + @Override + public boolean contains(NStage stage) { + return stage.compareTo(getStart()) >= 0 && stage.compareTo(getEnd()) <= 0; + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/next/NPlayField.java b/src/net/sourceforge/plantuml/nwdiag/next/NPlayField.java new file mode 100644 index 000000000..c141063dc --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/next/NPlayField.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.nwdiag.next; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class NPlayField { + + private final List stages = new ArrayList<>(); + + private final List bars = new ArrayList<>(); + private final List boxes = new ArrayList<>(); + + public NStage getStage(int num) { + while (stages.size() <= num) { + stages.add(new NStage(stages.size())); + } + return stages.get(num); + } + + public NStage createNewStage() { + return getStage(stages.size()); + } + + public void add(NBar bar) { + if (bar.getParent() == null) { + final NBox single = new NBox(); + single.add(bar); + bar.setParent(single); + boxes.add(bar.getParent()); + } else if (boxes.contains(bar.getParent()) == false) { + boxes.add(bar.getParent()); + } + } + + public Map doLayout() { + final NTetris tetris = new NTetris<>(); + for (NBox box : boxes) { + tetris.add(box); + } + final Map pos = tetris.getPositions(); + + final Map result = new HashMap<>(); + + for (Entry ent : pos.entrySet()) { + final NBox box = ent.getKey(); + final int boxPos = ent.getValue(); + + final Map tmp = box.getPositions(); + for (Entry ent2 : tmp.entrySet()) { + result.put(ent2.getKey(), boxPos + ent.getValue()); + } + + } + return Collections.unmodifiableMap(result); + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/next/NStage.java b/src/net/sourceforge/plantuml/nwdiag/next/NStage.java new file mode 100644 index 000000000..7f9b3e48a --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/next/NStage.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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.nwdiag.next; + +import java.util.Objects; + +public class NStage implements Comparable { + + private final int number; + + public NStage(int number) { + this.number = number; + } + + @Override + public String toString() { + return "S" + number; + } + + @Override + public int compareTo(NStage other) { + return Integer.compare(this.number, other.number); + } + + public int getNumber() { + return number; + } + + public static NStage getMin(NStage stage1, NStage stage2) { + if (stage1.number < stage2.number) { + return stage1; + } + return stage2; + } + + public static NStage getMax(NStage stage1, NStage stage2) { + if (stage1.number > stage2.number) { + return stage1; + } + return stage2; + } + +} diff --git a/src/net/sourceforge/plantuml/nwdiag/next/NTetris.java b/src/net/sourceforge/plantuml/nwdiag/next/NTetris.java new file mode 100644 index 000000000..59f3da390 --- /dev/null +++ b/src/net/sourceforge/plantuml/nwdiag/next/NTetris.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.nwdiag.next; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +public class NTetris { + + private final Map all = new LinkedHashMap<>(); + private final BooleanGrid grid = new BooleanGrid(); + + public void add(S element) { + int x = 0; + while (true) { + if (grid.isSpaceAvailable(element, x)) { + all.put(element, x); + grid.useSpace(element, x); + return; + } + x++; + if (x > 100) { + throw new IllegalStateException(); + } + } + } + + public final Map getPositions() { + return Collections.unmodifiableMap(all); + } + + public int getNWidth() { + int max = 0; + for (Entry ent : all.entrySet()) { + max = Math.max(max, ent.getValue() + ent.getKey().getNWidth()); + } + return max; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/rosetta/URosetta.java b/src/net/sourceforge/plantuml/nwdiag/next/Staged.java similarity index 86% rename from src/net/sourceforge/plantuml/creole/rosetta/URosetta.java rename to src/net/sourceforge/plantuml/nwdiag/next/Staged.java index dc366d561..b901c3554 100644 --- a/src/net/sourceforge/plantuml/creole/rosetta/URosetta.java +++ b/src/net/sourceforge/plantuml/nwdiag/next/Staged.java @@ -30,12 +30,18 @@ * * * Original Author: Arnaud Roques - * * */ -package net.sourceforge.plantuml.creole.rosetta; +package net.sourceforge.plantuml.nwdiag.next; -import net.sourceforge.plantuml.ugraphic.UShape; +public interface Staged { + + public NStage getStart(); + + public NStage getEnd(); + + public int getNWidth(); + + public boolean contains(NStage stage); -public interface URosetta extends UShape { } diff --git a/src/net/sourceforge/plantuml/project/GanttArrow.java b/src/net/sourceforge/plantuml/project/GanttArrow.java index fa0f3c4dc..af6f16f02 100644 --- a/src/net/sourceforge/plantuml/project/GanttArrow.java +++ b/src/net/sourceforge/plantuml/project/GanttArrow.java @@ -129,7 +129,7 @@ public class GanttArrow implements UDrawable { } else { x1 = getX(source.getAttribute(), getSource(), Direction.RIGHT); y1 = getSource().getY(stringBounder, Direction.RIGHT); - final double y1b = getDestination().getY(stringBounder); + final double y1b = getDestination().getY(stringBounder).getCurrentValue(); drawLine(ug, x1, y1, x1 + 6, y1, x1 + 6, y1b, x2 - 8, y1b, x2 - 8, y2, x2, y2); } } else if (this.atStart == Direction.RIGHT && this.atEnd == Direction.LEFT) { diff --git a/src/net/sourceforge/plantuml/project/GanttDiagram.java b/src/net/sourceforge/plantuml/project/GanttDiagram.java index 5b328651c..9855c145c 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagram.java @@ -45,6 +45,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.regex.Matcher; @@ -92,6 +93,9 @@ import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.WeekNumberStrategy; import net.sourceforge.plantuml.project.timescale.TimeScale; +import net.sourceforge.plantuml.real.Real; +import net.sourceforge.plantuml.real.RealOrigin; +import net.sourceforge.plantuml.real.RealUtils; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.SName; @@ -129,6 +133,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit private PrintScale printScale = PrintScale.DAILY; private double factorScale = 1.0; + private Locale locale = Locale.ENGLISH; private Day today; private double totalHeightWithoutFooter; @@ -138,6 +143,13 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit private Day printStart; private Day printEnd; + private final RealOrigin origin = RealUtils.createOrigin(); + + public CommandExecutionResult changeLanguage(String lang) { + this.locale = new Locale(lang); + return CommandExecutionResult.ok(); + } + public DiagramDescription getDescription() { return new DiagramDescription("(Project)"); } @@ -236,10 +248,13 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit if (HColorUtils.isTransparent(back) == false) { final URectangle rect1 = new URectangle(calculateDimension(ug.getStringBounder()).getWidth(), timeHeader.getTimeHeaderHeight()); - final URectangle rect2 = new URectangle(calculateDimension(ug.getStringBounder()).getWidth(), - timeHeader.getTimeFooterHeight()); ug.apply(back.bg()).draw(rect1); - ug.apply(back.bg()).apply(UTranslate.dy(totalHeightWithoutFooter)).draw(rect2); + if (showFootbox) { + final URectangle rect2 = new URectangle( + calculateDimension(ug.getStringBounder()).getWidth(), + timeHeader.getTimeFooterHeight()); + ug.apply(back.bg()).apply(UTranslate.dy(totalHeightWithoutFooter)).draw(rect2); + } } timeHeader.drawTimeHeader(ug, totalHeightWithoutFooter); @@ -300,25 +315,28 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit private TimeHeader getTimeHeader() { if (openClose.getCalendar() == null) { - return new TimeHeaderSimple(getFactorScale(), min, max, getClosedStyle(), getIHtmlColorSet(), - getSkinParam().getThemeStyle()); + return new TimeHeaderSimple(getTimelineStyle(), getClosedStyle(), getFactorScale(), min, max, + getIHtmlColorSet(), getSkinParam().getThemeStyle()); } else if (printScale == PrintScale.DAILY) { - return new TimeHeaderDaily(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(), - colorDaysOfWeek, nameDays, printStart, printEnd, getClosedStyle(), getIHtmlColorSet(), - getSkinParam().getThemeStyle()); + return new TimeHeaderDaily(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), + openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, nameDays, printStart, + printEnd, getIHtmlColorSet(), getSkinParam().getThemeStyle()); } else if (printScale == PrintScale.WEEKLY) { - return new TimeHeaderWeekly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(), - colorDaysOfWeek, weekNumberStrategy, getClosedStyle(), getIHtmlColorSet(), - getSkinParam().getThemeStyle()); + return new TimeHeaderWeekly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), + openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, weekNumberStrategy, + getIHtmlColorSet(), getSkinParam().getThemeStyle()); } else if (printScale == PrintScale.MONTHLY) { - return new TimeHeaderMonthly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(), - colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet(), getSkinParam().getThemeStyle()); + return new TimeHeaderMonthly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), + openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(), + getSkinParam().getThemeStyle()); } else if (printScale == PrintScale.QUARTERLY) { - return new TimeHeaderQuarterly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(), - colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet(), getSkinParam().getThemeStyle()); + return new TimeHeaderQuarterly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), + openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(), + getSkinParam().getThemeStyle()); } else if (printScale == PrintScale.YEARLY) { - return new TimeHeaderYearly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays(), - colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet(), getSkinParam().getThemeStyle()); + return new TimeHeaderYearly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), + openClose.getCalendar(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(), + getSkinParam().getThemeStyle()); } else { throw new IllegalStateException(); } @@ -334,6 +352,11 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit .getMergedStyle(getCurrentStyleBuilder()); } + private Style getTimelineStyle() { + return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.timeline) + .getMergedStyle(getCurrentStyleBuilder()); + } + private double getTotalHeight(TimeHeader timeHeader) { if (showFootbox) { return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight(); @@ -347,7 +370,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit continue; } final TaskDraw draw = draws.get(task); - final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder())); + final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()).getCurrentValue()); draw.drawU(ug.apply(move)); } } @@ -372,7 +395,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit continue; } final TaskDraw draw = draws.get(task); - final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder())); + final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()).getCurrentValue()); draw.drawTitle(ug.apply(move), labelStrategy, colTitles, colBars); } } @@ -398,7 +421,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit } private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight, StringBounder stringBounder) { - double y = headerHeight; + Real y = origin.addFixed(headerHeight); for (Task task : tasks.values()) { final TaskDraw draw; if (task instanceof TaskSeparator) { @@ -419,22 +442,23 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote()); } if (task.getRow() == null) { - y += draw.getFullHeightTask(stringBounder); + y = y.addAtLeast(draw.getFullHeightTask(stringBounder)); } draws.put(task, draw); } - while (magicPushOnce(stringBounder)) { - // - } - if (lastY(stringBounder) != 0) { - y = lastY(stringBounder); + origin.compileNow(); + magicPush(stringBounder); + double yy = lastY(stringBounder); + if (yy == 0) { + yy = headerHeight; + } else { for (Resource res : resources.values()) { - final ResourceDraw draw = new ResourceDraw(this, res, timeScale, y, min, max); + final ResourceDraw draw = new ResourceDraw(this, res, timeScale, yy, min, max); res.setTaskDraw(draw); - y += draw.getHeight(); + yy += draw.getHeight(); } } - this.totalHeightWithoutFooter = y; + this.totalHeightWithoutFooter = yy; } private Collection getConstraints(Task task) { @@ -450,46 +474,33 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit private double lastY(StringBounder stringBounder) { double result = 0; for (TaskDraw td : draws.values()) { - result = Math.max(result, td.getY(stringBounder) + td.getHeightMax(stringBounder)); + result = Math.max(result, td.getY(stringBounder).getCurrentValue() + td.getHeightMax(stringBounder)); } return result; } - private boolean magicPushOnce(StringBounder stringBounder) { - final List notes = new ArrayList<>(); + private void magicPush(StringBounder stringBounder) { + final List notes = new ArrayList<>(); for (TaskDraw td : draws.values()) { final FingerPrint taskPrint = td.getFingerPrint(stringBounder); - for (FingerPrint note : notes) { - final double deltaY = note.overlap(taskPrint); - if (deltaY > 0) { - pushIncluding(td, deltaY); - return true; - } - } - final FingerPrint fingerPrintNote = td.getFingerPrintNote(stringBounder); + + if (td.getTrueRow() == null) + for (TaskDraw note : notes) { + final FingerPrint otherNote = note.getFingerPrintNote(stringBounder); + final double deltaY = otherNote.overlap(taskPrint); + if (deltaY > 0) { + final Real bottom = note.getY(stringBounder).addAtLeast(note.getHeightMax(stringBounder)); + td.getY(stringBounder).ensureBiggerThan(bottom); + origin.compileNow(); + } + + } + if (fingerPrintNote != null) { - notes.add(fingerPrintNote); + notes.add(td); } } - return false; - } - - private void pushIncluding(TaskDraw first, double deltaY) { - boolean skipping = true; - if (first.getTrueRow() != null) { - first = first.getTrueRow(); - } - for (TaskDraw td : draws.values()) { - if (td == first) { - skipping = false; - } - if (skipping) { - continue; - } - td.pushMe(deltaY + 1); - } - } private Day getStart(final TaskImpl tmp) { diff --git a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java index ea5735a72..14ac987a5 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java @@ -51,6 +51,7 @@ import net.sourceforge.plantuml.project.command.CommandFootbox; import net.sourceforge.plantuml.project.command.CommandGanttArrow; import net.sourceforge.plantuml.project.command.CommandGanttArrow2; import net.sourceforge.plantuml.project.command.CommandLabelOnColumn; +import net.sourceforge.plantuml.project.command.CommandLanguage; import net.sourceforge.plantuml.project.command.CommandNoteBottom; import net.sourceforge.plantuml.project.command.CommandPage; import net.sourceforge.plantuml.project.command.CommandPrintBetween; @@ -103,6 +104,7 @@ public class GanttDiagramFactory extends PSystemCommandFactory { cmds.add(new CommandSeparator()); cmds.add(new CommandWeekNumberStrategy()); + cmds.add(new CommandLanguage()); cmds.add(new CommandPrintScale()); cmds.add(new CommandPrintBetween()); cmds.add(new CommandPage()); diff --git a/src/net/sourceforge/plantuml/project/command/CommandLanguage.java b/src/net/sourceforge/plantuml/project/command/CommandLanguage.java new file mode 100644 index 000000000..ca1d32697 --- /dev/null +++ b/src/net/sourceforge/plantuml/project/command/CommandLanguage.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project.command; + +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.PrintScale; + +public class CommandLanguage extends SingleLineCommand2 { + + public CommandLanguage() { + super(getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandLanguage.class.getName(), RegexLeaf.start(), // + new RegexLeaf("language"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("LANG", "(\\w+)"), // + RegexLeaf.end()); // + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) { + return diagram.changeLanguage(arg.get("LANG", 0)); + } + +} diff --git a/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java index d3662c42b..1d5fa2c37 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java +++ b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java @@ -78,7 +78,7 @@ public class CommandPrintScale extends SingleLineCommand2 { final String scaleString = arg.get("SCALE", 0); final PrintScale scale = PrintScale.fromString(scaleString); diagram.setPrintScale(scale); - + final String zoom = arg.get("ZOOM", 0); if (zoom != null) { diagram.setFactorScale(Double.parseDouble(zoom)); diff --git a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java index 632f51770..be9b2f7bf 100644 --- a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java +++ b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java @@ -47,6 +47,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.timescale.TimeScale; +import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.Style; @@ -62,7 +63,7 @@ public abstract class AbstractTaskDraw implements TaskDraw { protected Url url; protected Display note; protected final TimeScale timeScale; - private double y; + private Real y; protected final String prettyDisplay; protected final Day start; private final StyleBuilder styleBuilder; @@ -82,7 +83,7 @@ public abstract class AbstractTaskDraw implements TaskDraw { this.note = note; } - public AbstractTaskDraw(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam, + public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) { this.y = y; this.colorSet = colorSet; @@ -133,29 +134,25 @@ public abstract class AbstractTaskDraw implements TaskDraw { return toTaskDraw.getTaskDraw(task.getRow()); } - final public double getY(StringBounder stringBounder) { + @Override + final public Real getY(StringBounder stringBounder) { if (task.getRow() == null) { return y; } return getTrueRow().getY(stringBounder); } - public void pushMe(double deltaY) { - if (task.getRow() == null) { - this.y += deltaY; - } - } - public final Task getTask() { return task; } + @Override public final double getY(StringBounder stringBounder, Direction direction) { final Style style = getStyle(); final ClockwiseTopRightBottomLeft margin = style.getMargin(); final ClockwiseTopRightBottomLeft padding = style.getPadding(); - final double y1 = margin.getTop() + getY(stringBounder); + final double y1 = margin.getTop() + getY(stringBounder).getCurrentValue(); final double y2 = y1 + getShapeHeight(stringBounder); if (direction == Direction.UP) { diff --git a/src/net/sourceforge/plantuml/project/draw/RectangleTask.java b/src/net/sourceforge/plantuml/project/draw/RectangleTask.java index 7ba912d1d..8b5eab410 100644 --- a/src/net/sourceforge/plantuml/project/draw/RectangleTask.java +++ b/src/net/sourceforge/plantuml/project/draw/RectangleTask.java @@ -70,17 +70,17 @@ public class RectangleTask { ug.apply(UTranslate.dy(height)).draw(hline); } - private void drawRect(UGraphic ug, int completion, HColor documentBackground, double width, double height) { - if (completion == 100 || completion == 0) { - if (completion == 0) + private void drawRect(double widthCompletion, UGraphic ug, HColor documentBackground, double width, double height) { + if (widthCompletion == -1 || widthCompletion == 0) { + if (widthCompletion == 0) ug = ug.apply(documentBackground.bg()); final URectangle rect = new URectangle(width, height); ug.draw(rect); } else { - final URectangle rect1 = new URectangle(width * completion / 100, height); + final URectangle rect1 = new URectangle(widthCompletion, height); ug.draw(rect1); - final URectangle rect2 = new URectangle(width * (100 - completion) / 100, height); - ug.apply(documentBackground.bg()).apply(UTranslate.dx(width * completion / 100)).draw(rect2); + final URectangle rect2 = new URectangle(width - widthCompletion, height); + ug.apply(documentBackground.bg()).apply(UTranslate.dx(widthCompletion)).draw(rect2); } } @@ -129,7 +129,7 @@ public class RectangleTask { for (int i = 1; i < segments.size() - 1; i++) { final Segment segment = segments.get(i); - drawPartly(ug, segment, height, documentBackground, i); + drawPartly(segment.getLength() * completion / 100, ug, segment, height, documentBackground, i); } final Segment last = segments.get(segments.size() - 1); @@ -142,9 +142,24 @@ public class RectangleTask { boolean oddEnd) { final ULine vline = ULine.vline(height); + final double sum = getFullSegmentsLength(); + final double lim = completion == 100 ? sum : sum * completion / 100; + double current = 0; + for (int i = 0; i < segments.size(); i++) { final Segment segment = segments.get(i); - drawPartly(ug, segment, height, documentBackground, i); + final double next = current + segment.getLength(); + final double widthCompletion; + if (lim >= next) + widthCompletion = -1; + else if (current >= lim) + widthCompletion = 0; + else { + assert current < lim && lim < next; + widthCompletion = lim - current; + } + + drawPartly(widthCompletion, ug, segment, height, documentBackground, i); if (!oddStart && i == 0) { ug.apply(UTranslate.dx(segment.getPos1())).draw(vline); @@ -152,10 +167,18 @@ public class RectangleTask { if (!oddEnd && i == segments.size() - 1) { ug.apply(UTranslate.dx(segment.getPos2())).draw(vline); } + current = next; } drawIntermediateDotted(ug, height); } + private double getFullSegmentsLength() { + double result = 0; + for (Segment seg : segments) + result += seg.getLength(); + return result; + } + private void drawIntermediateDotted(UGraphic ug, double height) { ug = ug.apply(new UStroke(2, 3, 1)); for (int i = 0; i < segments.size() - 1; i++) { @@ -167,14 +190,15 @@ public class RectangleTask { } } - private void drawPartly(UGraphic ug, final Segment segment, double height, HColor documentBackground, int i) { + private void drawPartly(double widthCompletion, UGraphic ug, final Segment segment, double height, + HColor documentBackground, int i) { double width = segment.getLength(); if (i != segments.size() - 1) { width++; } if (width > 0) { - drawRect(ug.apply(new HColorNone()).apply(UTranslate.dx(segment.getPos1())), completion, documentBackground, - width, height); + drawRect(widthCompletion, ug.apply(new HColorNone()).apply(UTranslate.dx(segment.getPos1())), + documentBackground, width, height); } double pos1 = segment.getPos1(); diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDraw.java b/src/net/sourceforge/plantuml/project/draw/TaskDraw.java index b4b16baa7..6c7db7dcd 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDraw.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDraw.java @@ -44,6 +44,7 @@ import net.sourceforge.plantuml.project.LabelStrategy; import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.lang.CenterBorderColor; +import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.ugraphic.UGraphic; public interface TaskDraw extends UDrawable { @@ -52,12 +53,10 @@ public interface TaskDraw extends UDrawable { public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note); - public double getY(StringBounder stringBounder); + public Real getY(StringBounder stringBounder); public double getY(StringBounder stringBounder, Direction direction); - public void pushMe(double deltaY); - public void drawTitle(UGraphic ug, LabelStrategy labelStrategy, double colTitles, double colBars); public double getTitleWidth(StringBounder stringBounder); diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java index 4462f0faf..37ebd0ef1 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java @@ -49,6 +49,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.timescale.TimeScale; +import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.Style; @@ -62,7 +63,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorSet; public class TaskDrawDiamond extends AbstractTaskDraw { - public TaskDrawDiamond(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam, + public TaskDrawDiamond(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) { super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet); } @@ -72,6 +73,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw { return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.milestone); } + @Override public double getHeightMax(StringBounder stringBounder) { return getFullHeightTask(stringBounder); } @@ -127,6 +129,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw { new SpriteContainerEmpty()); } + @Override public void drawU(UGraphic ug) { final Style style = getStyle(); @@ -151,14 +154,17 @@ public class TaskDrawDiamond extends AbstractTaskDraw { ug.draw(getDiamond(ug.getStringBounder())); } + @Override public FingerPrint getFingerPrintNote(StringBounder stringBounder) { return null; } + @Override public FingerPrint getFingerPrint(StringBounder stringBounder) { final double h = getFullHeightTask(stringBounder); final double startPos = timeScale.getStartingPosition(start); - return new FingerPrint(startPos, getY(stringBounder), startPos + h, getY(stringBounder) + h); + return new FingerPrint(startPos, getY(stringBounder).getCurrentValue(), startPos + h, + getY(stringBounder).getCurrentValue() + h); } private UShape getDiamond(StringBounder stringBounder) { @@ -171,6 +177,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw { return result; } + @Override public double getX1(TaskAttribute taskAttribute) { final double x1 = timeScale.getStartingPosition(start); final double x2 = timeScale.getEndingPosition(start); @@ -179,6 +186,7 @@ public class TaskDrawDiamond extends AbstractTaskDraw { return x1 + delta; } + @Override public double getX2(TaskAttribute taskAttribute) { final double x1 = timeScale.getStartingPosition(start); final double x2 = timeScale.getEndingPosition(start); diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java index 9d078a5a0..20474b6af 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java @@ -60,6 +60,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskImpl; import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.timescale.TimeScale; +import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.sequencediagram.graphic.Segment; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.style.PName; @@ -89,7 +90,7 @@ public class TaskDrawRegular extends AbstractTaskDraw { // private final double margin = 2; - public TaskDrawRegular(TimeScale timeScale, double y, String prettyDisplay, Day start, Day end, boolean oddStart, + public TaskDrawRegular(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, boolean oddStart, boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw, Collection constraints, StyleBuilder styleBuilder, HColorSet colorSet) { super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet); @@ -227,7 +228,7 @@ public class TaskDrawRegular extends AbstractTaskDraw { final double h = getFullHeightTask(stringBounder); final double startPos = timeScale.getStartingPosition(start); final double endPos = timeScale.getEndingPosition(end); - return new FingerPrint(startPos, getY(stringBounder), endPos - startPos, h); + return new FingerPrint(startPos, getY(stringBounder).getCurrentValue(), endPos - startPos, h); } public FingerPrint getFingerPrintNote(StringBounder stringBounder) { @@ -237,8 +238,8 @@ public class TaskDrawRegular extends AbstractTaskDraw { final Dimension2D dim = getOpaleNote().calculateDimension(stringBounder); final double startPos = timeScale.getStartingPosition(start); // final double endPos = timeScale.getEndingPosition(end); - return new FingerPrint(startPos, getY(stringBounder) + getYNotePosition(stringBounder), dim.getWidth(), - dim.getHeight()); + return new FingerPrint(startPos, getY(stringBounder).getCurrentValue() + getYNotePosition(stringBounder), + dim.getWidth(), dim.getHeight()); } private UGraphic applyColors(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java index 0cec0726c..b1a1679fa 100644 --- a/src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.timescale.TimeScale; +import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.SName; @@ -67,14 +68,14 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils; public class TaskDrawSeparator implements TaskDraw { private final TimeScale timeScale; - private double y; + private Real y; private final Day min; private final Day max; private final String name; private final StyleBuilder styleBuilder; private final HColorSet colorSet; - public TaskDrawSeparator(String name, TimeScale timeScale, double y, Day min, Day max, StyleBuilder styleBuilder, + public TaskDrawSeparator(String name, TimeScale timeScale, Real y, Day min, Day max, StyleBuilder styleBuilder, HColorSet colorSet) { this.styleBuilder = styleBuilder; this.colorSet = colorSet; @@ -126,6 +127,7 @@ public class TaskDrawSeparator implements TaskDraw { return getStyle().getFontConfiguration(styleBuilder.getSkinParam().getThemeStyle(), colorSet); } + @Override public void drawU(UGraphic ug) { final StringBounder stringBounder = ug.getStringBounder(); final double widthTitle = getTitle().calculateDimension(stringBounder).getWidth(); @@ -168,12 +170,20 @@ public class TaskDrawSeparator implements TaskDraw { } } + @Override public FingerPrint getFingerPrint(StringBounder stringBounder) { final double h = getFullHeightTask(stringBounder); final double end = timeScale.getEndingPosition(max); - return new FingerPrint(0, y, end, y + h); + return new FingerPrint(0, getY(stringBounder).getCurrentValue(), end, + getY(stringBounder).getCurrentValue() + h); } + @Override + public FingerPrint getFingerPrintNote(StringBounder stringBounder) { + return null; + } + + @Override public double getFullHeightTask(StringBounder stringBounder) { final ClockwiseTopRightBottomLeft padding = getStyle().getPadding(); final ClockwiseTopRightBottomLeft margin = getStyle().getMargin(); @@ -185,41 +195,41 @@ public class TaskDrawSeparator implements TaskDraw { return getTitle().calculateDimension(stringBounder).getHeight(); } - public double getY(StringBounder stringBounder) { + @Override + public Real getY(StringBounder stringBounder) { return y; } - public void pushMe(double deltaY) { - this.y += deltaY; - } - + @Override public TaskDraw getTrueRow() { return null; } + @Override public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note) { } + @Override public Task getTask() { throw new UnsupportedOperationException(); } + @Override public double getY(StringBounder stringBounder, Direction direction) { throw new UnsupportedOperationException(); } - public FingerPrint getFingerPrintNote(StringBounder stringBounder) { - return null; - } - + @Override public double getHeightMax(StringBounder stringBounder) { return getFullHeightTask(stringBounder); } + @Override public double getX1(TaskAttribute taskAttribute) { throw new UnsupportedOperationException(); } + @Override public double getX2(TaskAttribute taskAttribute) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java index d68328a92..2af17e795 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java @@ -68,28 +68,40 @@ public abstract class TimeHeader { } private final TimeScale timeScale; - private final Style style; + private final Style closedStyle; + private final Style timelineStyle; + private final HColorSet colorSet; private final ThemeStyle themeStyle; protected final Day min; protected final Day max; - public TimeHeader(Day min, Day max, TimeScale timeScale, Style style, HColorSet colorSet, ThemeStyle themeStyle) { + public TimeHeader(Style timelineStyle, Style closedStyle, Day min, Day max, TimeScale timeScale, HColorSet colorSet, + ThemeStyle themeStyle) { this.timeScale = timeScale; this.min = min; this.max = max; - this.style = Objects.requireNonNull(style); + this.closedStyle = Objects.requireNonNull(closedStyle); + this.timelineStyle = Objects.requireNonNull(timelineStyle); this.colorSet = colorSet; this.themeStyle = themeStyle; } protected final HColor closedBackgroundColor() { - return style.value(PName.BackGroundColor).asColor(themeStyle, colorSet); + return closedStyle.value(PName.BackGroundColor).asColor(themeStyle, colorSet); } protected final HColor closedFontColor() { - return style.value(PName.FontColor).asColor(themeStyle, colorSet); + return closedStyle.value(PName.FontColor).asColor(themeStyle, colorSet); + } + + protected final HColor openFontColor() { + return timelineStyle.value(PName.FontColor).asColor(themeStyle, colorSet); + } + + protected final HColor getBarColor() { + return timelineStyle.value(PName.LineColor).asColor(themeStyle, colorSet); } public abstract double getTimeHeaderHeight(); @@ -106,7 +118,12 @@ public abstract class TimeHeader { final double xmin = getTimeScale().getStartingPosition(min); final double xmax = getTimeScale().getEndingPosition(max); final ULine hline = ULine.hline(xmax - xmin); - ug.apply(HColorUtils.LIGHT_GRAY).apply(UTranslate.dy(y)).draw(hline); + ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline); + } + + protected final void drawVbar(UGraphic ug, double x, double y1, double y2) { + final ULine vbar = ULine.vline(y2 - y1); + ug.apply(getBarColor()).apply(new UTranslate(x, y1)).draw(vbar); } final protected FontConfiguration getFontConfiguration(int size, boolean bold, HColor color) { diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java index 57698a0fd..e19f65fc5 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project.draw; +import java.util.Locale; import java.util.Map; import net.sourceforge.plantuml.ThemeStyle; @@ -52,11 +53,13 @@ public abstract class TimeHeaderCalendar extends TimeHeader { protected final LoadPlanable defaultPlan; protected final Map colorDays; protected final Map colorDaysOfWeek; + protected final Locale locale; - public TimeHeaderCalendar(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map colorDays, - Map colorDaysOfWeek, TimeScale timeScale, Style style, HColorSet colorSet, - ThemeStyle themeStyle) { - super(min, max, timeScale, style, colorSet, themeStyle); + public TimeHeaderCalendar(Locale locale, Style timelineStyle, Style closedStyle, Day calendar, Day min, Day max, + LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, + TimeScale timeScale, HColorSet colorSet, ThemeStyle themeStyle) { + super(timelineStyle, closedStyle, min, max, timeScale, colorSet, themeStyle); + this.locale = locale; this.defaultPlan = defaultPlan; this.colorDays = colorDays; this.colorDaysOfWeek = colorDaysOfWeek; diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java index f725d0ea2..d3b49de6c 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project.draw; +import java.util.Locale; import java.util.Map; import net.sourceforge.plantuml.ThemeStyle; @@ -46,7 +47,6 @@ import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleDaily; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; @@ -65,11 +65,11 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { private final Map nameDays; - public TimeHeaderDaily(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, - Map colorDays, Map colorDaysOfWeek, Map nameDays, - Day printStart, Day printEnd, Style style, HColorSet colorSet, ThemeStyle themeStyle) { - super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, - new TimeScaleDaily(scale, calendar, printStart), style, colorSet, themeStyle); + public TimeHeaderDaily(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, + Day max, LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, + Map nameDays, Day printStart, Day printEnd, HColorSet colorSet, ThemeStyle themeStyle) { + super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, + new TimeScaleDaily(scale, calendar, printStart), colorSet, themeStyle); this.nameDays = nameDays; } @@ -79,12 +79,38 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { drawTextsDayOfWeek(ug.apply(UTranslate.dy(Y_POS_ROW16()))); drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28()))); drawMonths(ug); - drawVBars(ug, totalHeightWithoutFooter); - drawVbar(ug, getTimeScale().getStartingPosition(max.increment()), 0, - totalHeightWithoutFooter + getTimeFooterHeight()); + printSmallVbars(ug, totalHeightWithoutFooter); +// drawVBars(ug, totalHeightWithoutFooter); +// drawVbar(ug, getTimeScale().getStartingPosition(max.increment()), 0, +// totalHeightWithoutFooter + getTimeFooterHeight()); printNamedDays(ug); - drawHline(ug, 0); + drawHline(ug, getFullHeaderHeight()); + drawHline(ug, totalHeightWithoutFooter); + +// drawHline(ug, 0); +// drawHline(ug, getFullHeaderHeight()); + } + + private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) { + for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { + drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter); + } + drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter); + } + + private void drawVBars(UGraphic ug, double totalHeightWithoutFooter) { + MonthYear last = null; + for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { + double startingY = getFullHeaderHeight(); + double len = totalHeightWithoutFooter; + if (wink.monthYear().equals(last) == false) { + startingY = 0; + last = wink.monthYear(); + len += 24 + 13; + } + drawVbar(ug, getTimeScale().getStartingPosition(wink), startingY, len); + } } @Override @@ -92,8 +118,8 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { drawTextDayOfMonth(ug.apply(UTranslate.dy(12))); drawTextsDayOfWeek(ug); drawMonths(ug.apply(UTranslate.dy(24))); - drawHline(ug, 0); - drawHline(ug, getTimeFooterHeight()); +// drawHline(ug, 0); +// drawHline(ug, getTimeFooterHeight()); } private void drawTextsDayOfWeek(UGraphic ug) { @@ -101,7 +127,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { final double x1 = getTimeScale().getStartingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink); final HColor textColor = getTextBackColor(wink); - printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(), 10, false, textColor), x1, x2); + printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale), 10, false, textColor), x1, x2); } } @@ -118,7 +144,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { if (defaultPlan.getLoadAt(wink) <= 0) { return closedFontColor(); } - return HColorUtils.BLACK; + return openFontColor(); } private void drawMonths(final UGraphic ug) { @@ -140,32 +166,13 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { } } - private void drawVBars(UGraphic ug, double totalHeightWithoutFooter) { - MonthYear last = null; - for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { - double startingY = getFullHeaderHeight(); - double len = totalHeightWithoutFooter; - if (wink.monthYear().equals(last) == false) { - startingY = 0; - last = wink.monthYear(); - len += 24 + 13; - } - drawVbar(ug, getTimeScale().getStartingPosition(wink), startingY, len); - } - } - private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock tiny = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK); - final TextBlock small = getTextBlock(monthYear.longName(), 12, true, HColorUtils.BLACK); - final TextBlock big = getTextBlock(monthYear.longNameYYYY(), 12, true, HColorUtils.BLACK); + final TextBlock tiny = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor()); + final TextBlock small = getTextBlock(monthYear.longName(locale), 12, true, openFontColor()); + final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale), 12, true, openFontColor()); printCentered(ug, false, start, end, tiny, small, big); } - private void drawVbar(UGraphic ug, double x, double y1, double y2) { - final ULine vbar = ULine.vline(y2 - y1); - ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar); - } - private void printNamedDays(final UGraphic ug) { if (nameDays.size() > 0) { String last = null; @@ -174,7 +181,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar { if (name != null && name.equals(last) == false) { final double x1 = getTimeScale().getStartingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink); - final TextBlock label = getTextBlock(name, 12, false, HColorUtils.BLACK); + final TextBlock label = getTextBlock(name, 12, false, openFontColor()); final double h = label.calculateDimension(ug.getStringBounder()).getHeight(); double y1 = getTimeHeaderHeight(); double y2 = getFullHeaderHeight(); diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java index 0456ec043..ffc111c9d 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project.draw; +import java.util.Locale; import java.util.Map; import net.sourceforge.plantuml.ThemeStyle; @@ -46,11 +47,9 @@ import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; -import net.sourceforge.plantuml.ugraphic.color.HColorUtils; public class TimeHeaderMonthly extends TimeHeaderCalendar { @@ -62,11 +61,11 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { return 16 + 13 - 1; } - public TimeHeaderMonthly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, - Map colorDays, Map colorDaysOfWeek, Style style, HColorSet colorSet, - ThemeStyle themeStyle) { - super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale), - style, colorSet, themeStyle); + public TimeHeaderMonthly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, + Day max, LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, + HColorSet colorSet, ThemeStyle themeStyle) { + super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, + new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); } @Override @@ -132,21 +131,16 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar { } private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK); + final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, openFontColor()); printCentered(ug, false, start, end, small); } private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock(monthYear.shortName(), 10, false, HColorUtils.BLACK); - final TextBlock big = getTextBlock(monthYear.longName(), 10, false, HColorUtils.BLACK); + final TextBlock small = getTextBlock(monthYear.shortName(locale), 10, false, openFontColor()); + final TextBlock big = getTextBlock(monthYear.longName(locale), 10, false, openFontColor()); printCentered(ug, false, start, end, small, big); } - private void drawVbar(UGraphic ug, double x, double y1, double y2) { - final ULine vbar = ULine.vline(y2 - y1); - ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar); - } - private void printLeft(UGraphic ug, TextBlock text, double start) { text.drawU(ug.apply(UTranslate.dx(start))); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java index b132ebc56..dec281b21 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project.draw; +import java.util.Locale; import java.util.Map; import net.sourceforge.plantuml.ThemeStyle; @@ -46,7 +47,6 @@ import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; @@ -62,11 +62,11 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { return 16 + 13 - 1; } - public TimeHeaderQuarterly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, - Map colorDays, Map colorDaysOfWeek, Style style, HColorSet colorSet, - ThemeStyle themeStyle) { - super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale), - style, colorSet, themeStyle); + public TimeHeaderQuarterly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, + LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, + HColorSet colorSet, ThemeStyle themeStyle) { + super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, + new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); } @Override @@ -136,20 +136,15 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar { } private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK); + final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, openFontColor()); printCentered(ug, false, start, end, small); } private void printQuarter(UGraphic ug, String quarter, double start, double end) { - final TextBlock small = getTextBlock(quarter, 10, false, HColorUtils.BLACK); + final TextBlock small = getTextBlock(quarter, 10, false, openFontColor()); printCentered(ug, false, start, end, small); } - private void drawVbar(UGraphic ug, double x, double y1, double y2) { - final ULine vbar = ULine.vline(y2 - y1); - ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar); - } - private void printLeft(UGraphic ug, TextBlock text, double start) { text.drawU(ug.apply(UTranslate.dx(start))); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java index 3daf15648..60eca9902 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java @@ -69,15 +69,16 @@ public class TimeHeaderSimple extends TimeHeader { return 0; } - public TimeHeaderSimple(double scale, Day min, Day max, Style style, HColorSet colorSet, ThemeStyle themeStyle) { - super(min, max, new TimeScaleWink(scale), style, colorSet, themeStyle); + public TimeHeaderSimple(Style timelineStyle, Style closedStyle, double scale, Day min, Day max, HColorSet colorSet, + ThemeStyle themeStyle) { + super(timelineStyle, closedStyle, min, max, new TimeScaleWink(scale), colorSet, themeStyle); } private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) { final ULine vbar = ULine.vline(totalHeightWithoutFooter); for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) { final double x1 = timeScale.getStartingPosition(i); - ug.apply(HColorUtils.LIGHT_GRAY).apply(UTranslate.dx(x1)).draw(vbar); + ug.apply(getBarColor()).apply(UTranslate.dx(x1)).draw(vbar); } } @@ -85,7 +86,7 @@ public class TimeHeaderSimple extends TimeHeader { for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) { final String number = "" + (i.getAbsoluteDayNum() + 1); final TextBlock num = Display.getWithNewlines(number).create( - getFontConfiguration(10, false, HColorUtils.BLACK), HorizontalAlignment.LEFT, + getFontConfiguration(10, false, openFontColor()), HorizontalAlignment.LEFT, new SpriteContainerEmpty()); final double x1 = timeScale.getStartingPosition(i); final double x2 = timeScale.getEndingPosition(i); @@ -103,8 +104,8 @@ public class TimeHeaderSimple extends TimeHeader { final double xmax = getTimeScale().getEndingPosition(max); drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter); drawSimpleDayCounter(ug, getTimeScale()); - ug.apply(HColorUtils.LIGHT_GRAY).draw(ULine.hline(xmax - xmin)); - ug.apply(HColorUtils.LIGHT_GRAY).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin)); + ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin)); + ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin)); } @@ -115,7 +116,7 @@ public class TimeHeaderSimple extends TimeHeader { drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight()); ug = ug.apply(UTranslate.dy(3)); drawSimpleDayCounter(ug, getTimeScale()); - ug.apply(HColorUtils.LIGHT_GRAY).draw(ULine.hline(xmax - xmin)); + ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin)); } } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java index 19778befe..1d4d398fc 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project.draw; +import java.util.Locale; import java.util.Map; import net.sourceforge.plantuml.ThemeStyle; @@ -47,7 +48,6 @@ import net.sourceforge.plantuml.project.time.WeekNumberStrategy; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; @@ -65,11 +65,11 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { return 16; } - public TimeHeaderWeekly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, - Map colorDays, Map colorDaysOfWeek, WeekNumberStrategy weekNumberStrategy, - Style style, HColorSet colorSet, ThemeStyle themeStyle) { - super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale), - style, colorSet, themeStyle); + public TimeHeaderWeekly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, + LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, + WeekNumberStrategy weekNumberStrategy, HColorSet colorSet, ThemeStyle themeStyle) { + super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, + new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); this.weekNumberStrategy = weekNumberStrategy; } @@ -130,7 +130,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) { final String num = "" + wink.getWeekOfYear(weekNumberStrategy); // final String num = "" + wink.getDayOfMonth(); - final TextBlock textBlock = getTextBlock(num, 10, false, HColorUtils.BLACK); + final TextBlock textBlock = getTextBlock(num, 10, false, openFontColor()); printLeft(ug.apply(UTranslate.dy(Y_POS_ROW16())), textBlock, getTimeScale().getStartingPosition(wink) + 5); } @@ -138,16 +138,11 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar { } private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK); - final TextBlock big = getTextBlock(monthYear.shortNameYYYY(), 12, true, HColorUtils.BLACK); + final TextBlock small = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor()); + final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale), 12, true, openFontColor()); printCentered(ug, false, start, end, small, big); } - private void drawVbar(UGraphic ug, double x, double y1, double y2) { - final ULine vbar = ULine.vline(y2 - y1); - ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar); - } - private void printLeft(UGraphic ug, TextBlock text, double start) { text.drawU(ug.apply(UTranslate.dx(start))); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java index f308b0d96..a08dcb2f1 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project.draw; +import java.util.Locale; import java.util.Map; import net.sourceforge.plantuml.ThemeStyle; @@ -46,7 +47,6 @@ import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet; @@ -62,11 +62,11 @@ public class TimeHeaderYearly extends TimeHeaderCalendar { return 20 - 1; } - public TimeHeaderYearly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, - Map colorDays, Map colorDaysOfWeek, Style style, HColorSet colorSet, - ThemeStyle themeStyle) { - super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale), - style, colorSet, themeStyle); + public TimeHeaderYearly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, + LoadPlanable defaultPlan, Map colorDays, Map colorDaysOfWeek, + HColorSet colorSet, ThemeStyle themeStyle) { + super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, + new TimeScaleCompressed(calendar, scale), colorSet, themeStyle); } @Override @@ -107,15 +107,10 @@ public class TimeHeaderYearly extends TimeHeaderCalendar { } private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { - final TextBlock small = getTextBlock("" + monthYear.year(), 14, true, HColorUtils.BLACK); + final TextBlock small = getTextBlock("" + monthYear.year(), 14, true, openFontColor()); printCentered(ug, true, start, end, small); } - private void drawVbar(UGraphic ug, double x, double y1, double y2) { - final ULine vbar = ULine.vline(y2 - y1); - ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar); - } - @Override public double getFullHeaderHeight() { return getTimeHeaderHeight(); diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java index 01a9e9f7c..070f4117d 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java @@ -93,5 +93,5 @@ public class SubjectDayOfWeek implements Subject { } } - + } diff --git a/src/net/sourceforge/plantuml/project/time/DayOfWeek.java b/src/net/sourceforge/plantuml/project/time/DayOfWeek.java index 7680f8cd7..66c7483c4 100644 --- a/src/net/sourceforge/plantuml/project/time/DayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/time/DayOfWeek.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.project.time; import java.text.SimpleDateFormat; +import java.time.format.TextStyle; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; @@ -72,10 +73,10 @@ public enum DayOfWeek { return DayOfWeek.values()[result - 2]; } - public static synchronized String timeToString(long value) { - gmt.setTimeInMillis(value); - return fromTime(value).shortName() + " " + dateFormatGmt.format(gmt.getTime()); - } +// private static synchronized String timeToString(Locale locale, long value) { +// gmt.setTimeInMillis(value); +// return fromTime(value).shortName(locale) + " " + dateFormatGmt.format(gmt.getTime()); +// } static public String getRegexString() { final StringBuilder sb = new StringBuilder(); @@ -106,7 +107,13 @@ public enum DayOfWeek { return DayOfWeek.values()[(h + 5) % 7]; } - public String shortName() { - return StringUtils.capitalize(name().substring(0, 2)); + public String shortName(Locale locale) { + if (locale == Locale.ENGLISH) + return StringUtils.capitalize(name().substring(0, 2)); + final String s = StringUtils.capitalize( + java.time.DayOfWeek.valueOf(this.toString()).getDisplayName(TextStyle.SHORT_STANDALONE, locale)); + if (s.length() > 2) + return s.substring(0, 2); + return s; } } diff --git a/src/net/sourceforge/plantuml/project/time/Month.java b/src/net/sourceforge/plantuml/project/time/Month.java index 1b6bb8351..4346f6f05 100644 --- a/src/net/sourceforge/plantuml/project/time/Month.java +++ b/src/net/sourceforge/plantuml/project/time/Month.java @@ -35,6 +35,9 @@ */ package net.sourceforge.plantuml.project.time; +import java.time.format.TextStyle; +import java.util.Locale; + import net.sourceforge.plantuml.StringUtils; public enum Month { @@ -48,12 +51,21 @@ public enum Month { this.daysPerMonth = daysPerMonth; } - public String shortName() { - return longName().substring(0, 3); + public String shortName(Locale locale) { + if (locale == Locale.ENGLISH) + return longName(locale).substring(0, 3); + + return StringUtils.capitalize( + java.time.Month.valueOf(this.toString()).getDisplayName(TextStyle.SHORT_STANDALONE, locale)); + } - public String longName() { - return StringUtils.capitalize(name()); + public String longName(Locale locale) { + if (locale == Locale.ENGLISH) + return StringUtils.capitalize(name()); + + return StringUtils + .capitalize(java.time.Month.valueOf(this.toString()).getDisplayName(TextStyle.FULL_STANDALONE, locale)); } static public String getRegexString() { diff --git a/src/net/sourceforge/plantuml/project/time/MonthYear.java b/src/net/sourceforge/plantuml/project/time/MonthYear.java index 9a62258dc..e7f8bb4b0 100644 --- a/src/net/sourceforge/plantuml/project/time/MonthYear.java +++ b/src/net/sourceforge/plantuml/project/time/MonthYear.java @@ -35,6 +35,8 @@ */ package net.sourceforge.plantuml.project.time; +import java.util.Locale; + public class MonthYear implements Comparable { private final int year; @@ -44,20 +46,20 @@ public class MonthYear implements Comparable { return new MonthYear(year, month); } - public String shortName() { - return month.shortName(); + public String shortName(Locale locale) { + return month.shortName(locale); } - public String shortNameYYYY() { - return month.shortName() + " " + year; + public String shortNameYYYY(Locale locale) { + return month.shortName(locale) + " " + year; } - public String longName() { - return month.longName(); + public String longName(Locale locale) { + return month.longName(locale); } - public String longNameYYYY() { - return month.longName() + " " + year; + public String longNameYYYY(Locale locale) { + return month.longName(locale) + " " + year; } private MonthYear(int year, Month month) { diff --git a/src/net/sourceforge/plantuml/security/SFile.java b/src/net/sourceforge/plantuml/security/SFile.java index 65543b37a..aea3f3350 100644 --- a/src/net/sourceforge/plantuml/security/SFile.java +++ b/src/net/sourceforge/plantuml/security/SFile.java @@ -114,7 +114,7 @@ public class SFile implements Comparable { } public boolean exists() { - if (isFileOk()) + if (internal != null && isFileOk()) return internal.exists(); return false; } @@ -124,11 +124,11 @@ public class SFile implements Comparable { } public boolean isAbsolute() { - return internal.isAbsolute(); + return internal != null && internal.isAbsolute(); } public boolean isDirectory() { - return internal.exists() && internal.isDirectory(); + return internal != null && internal.exists() && internal.isDirectory(); } public String getName() { @@ -136,7 +136,7 @@ public class SFile implements Comparable { } public boolean isFile() { - return internal.isFile(); + return internal != null && internal.isFile(); } public long lastModified() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java index b02923404..c6b11ddf3 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java +++ b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java @@ -193,11 +193,11 @@ public abstract class AbstractMessage implements EventWithDeactivate, WithStyle && note.getPosition() != NotePosition.BOTTOM && note.getPosition() != NotePosition.TOP) { throw new IllegalArgumentException(); } - note = note.withPosition(overideNotePosition(note.getPosition())); + note = note.withPosition(overrideNotePosition(note.getPosition())); this.noteOnMessages.add(note); } - protected NotePosition overideNotePosition(NotePosition notePosition) { + protected NotePosition overrideNotePosition(NotePosition notePosition) { return notePosition; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java index a057f984f..6733523f1 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java +++ b/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java @@ -58,7 +58,7 @@ public class MessageExo extends AbstractMessage { } @Override - protected NotePosition overideNotePosition(NotePosition notePosition) { + protected NotePosition overrideNotePosition(NotePosition notePosition) { if (type == MessageExoType.FROM_LEFT || type == MessageExoType.TO_LEFT) { return NotePosition.RIGHT; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java index ca06a1c98..ff35b429f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java @@ -60,6 +60,8 @@ import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; abstract class CommandExoArrowAny extends SingleLineCommand2 { + protected static final String SHORT = "SHORT"; + public CommandExoArrowAny(IRegex pattern) { super(pattern); } @@ -204,7 +206,7 @@ abstract class CommandExoArrowAny extends SingleLineCommand2 { abstract MessageExoType getMessageExoType(RegexResult arg2); private boolean isShortArrow(RegexResult arg2) { - final String s = arg2.get("SHORT", 0); + final String s = arg2.get(SHORT, 0); if (s != null && s.contains("?")) { return true; } @@ -212,7 +214,7 @@ abstract class CommandExoArrowAny extends SingleLineCommand2 { } private boolean containsSymbolExterior(RegexResult arg2, String symbol) { - final String s = arg2.get("SHORT", 0); + final String s = arg2.get(SHORT, 0); if (s != null && s.contains(symbol)) { return true; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java index 732b72ad8..73f4191b7 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java @@ -54,7 +54,7 @@ public class CommandExoArrowLeft extends CommandExoArrowAny { return RegexConcat.build(CommandExoArrowLeft.class.getName(), RegexLeaf.start(), // new RegexLeaf("PARALLEL", "(&[%s]*)?"), // new RegexLeaf("ANCHOR", CommandArrow.ANCHOR), // - new RegexLeaf("SHORT", "([?\\[\\]][ox]?)?"), // + new RegexLeaf(SHORT, "([?\\[\\]][ox]?)?"), // new RegexOr( // new RegexConcat( // new RegexLeaf("ARROW_BOTHDRESSING", "(< notes = new ArrayList<>(); for (Note noteOnMessage : m.getNoteOnMessages()) { final ISkinParam sk = noteOnMessage.getSkinParamBackcolored(drawableSet.getSkinParam()); - final Component note = drawableSet.getSkin().createComponent(noteOnMessage.getUsedStyles(), - noteOnMessage.getNoteStyle().getNoteComponentType(), null, sk, noteOnMessage.getStrings()); + final Component note = drawableSet.getSkin().createComponentNote(noteOnMessage.getUsedStyles(), + noteOnMessage.getNoteStyle().getNoteComponentType(), sk, noteOnMessage.getStrings()); notes.add(note); } if (m.isParallel()) { @@ -467,8 +472,9 @@ class DrawableSetInitializer { p2 = p; } } - final NoteBox noteBox = new NoteBox(freeY2.getFreeY(range), drawableSet.getSkin().createComponent( - n.getUsedStyles(), type, null, skinParam, n.getStrings()), p1, p2, n.getPosition(), n.getUrl()); + final Component component = drawableSet.getSkin().createComponentNote(n.getUsedStyles(), type, skinParam, + n.getStrings(), n.getPosition()); + final NoteBox noteBox = new NoteBox(freeY2.getFreeY(range), component, p1, p2, n.getPosition(), n.getUrl()); return noteBox; } @@ -477,8 +483,8 @@ class DrawableSetInitializer { for (Note n : notes) { final NoteBox noteBox = createNoteBox(stringBounder, n, range); final ParticipantBox p1 = drawableSet.getLivingParticipantBox(n.getParticipant()).getParticipantBox(); - final ParticipantBox p2 = n.getParticipant2() == null ? null : drawableSet.getLivingParticipantBox( - n.getParticipant2()).getParticipantBox(); + final ParticipantBox p2 = n.getParticipant2() == null ? null + : drawableSet.getLivingParticipantBox(n.getParticipant2()).getParticipantBox(); notesBoxes.add(noteBox, p1, p2); } notesBoxes.ensureConstraints(stringBounder, constraintSet); @@ -522,8 +528,8 @@ class DrawableSetInitializer { final Component comp = drawableSet.getSkin().createComponent(null, ComponentType.DESTROY, null, drawableSet.getSkinParam(), null); final double delta = comp.getPreferredHeight(stringBounder) / 2; - final LivingParticipantBox livingParticipantBox = drawableSet.getLivingParticipantBox(lifeEvent - .getParticipant()); + final LivingParticipantBox livingParticipantBox = drawableSet + .getLivingParticipantBox(lifeEvent.getParticipant()); double pos2 = y; if (message == null) { pos2 = y; @@ -550,18 +556,18 @@ class DrawableSetInitializer { } private void prepareReference(StringBounder stringBounder, Reference reference, ParticipantRange range) { - final LivingParticipantBox p1 = drawableSet.getLivingParticipantBox(drawableSet.getFirst(reference - .getParticipant())); - final LivingParticipantBox p2 = drawableSet.getLivingParticipantBox(drawableSet.getLast(reference - .getParticipant())); + final LivingParticipantBox p1 = drawableSet + .getLivingParticipantBox(drawableSet.getFirst(reference.getParticipant())); + final LivingParticipantBox p2 = drawableSet + .getLivingParticipantBox(drawableSet.getLast(reference.getParticipant())); final ISkinParam skinParam = new SkinParamBackcoloredReference(drawableSet.getSkinParam(), reference.getBackColorElement(), reference.getBackColorGeneral()); Display strings = Display.empty(); strings = strings.add("ref"); strings = strings.addAll(reference.getStrings()); - final Component comp = drawableSet.getSkin().createComponent(reference.getUsedStyles(), - ComponentType.REFERENCE, null, skinParam, strings); + final Component comp = drawableSet.getSkin().createComponent(reference.getUsedStyles(), ComponentType.REFERENCE, + null, skinParam, strings); final GraphicalReference graphicalReference = new GraphicalReference(freeY2.getFreeY(range), comp, p1, p2, reference.getUrl()); @@ -625,8 +631,8 @@ class DrawableSetInitializer { participantDisplay); final Component tail = drawableSet.getSkin().createComponent(p.getUsedStyles(), tailType, null, skinParam, participantDisplay); - final Style style = this.defaultLineType.getDefaultStyleDefinition().getMergedStyle( - skinParam.getCurrentStyleBuilder()); + final Style style = this.defaultLineType.getDefaultStyleDefinition() + .getMergedStyle(skinParam.getCurrentStyleBuilder()); final Component line = drawableSet.getSkin().createComponent(new Style[] { style }, this.defaultLineType, null, drawableSet.getSkinParam(), participantDisplay); final Component delayLine = drawableSet.getSkin().createComponent(null, ComponentType.DELAY_LINE, null, @@ -635,12 +641,12 @@ class DrawableSetInitializer { skinParam.maxAsciiMessageLength() > 0 ? 1 : 5); final Component comp = drawableSet.getSkin().createComponent( - new Style[] { ComponentType.ALIVE_BOX_CLOSE_CLOSE.getDefaultStyleDefinition().getMergedStyle( - drawableSet.getSkinParam().getCurrentStyleBuilder()) }, ComponentType.ALIVE_BOX_CLOSE_CLOSE, - null, drawableSet.getSkinParam(), null); + new Style[] { ComponentType.ALIVE_BOX_CLOSE_CLOSE.getDefaultStyleDefinition() + .getMergedStyle(drawableSet.getSkinParam().getCurrentStyleBuilder()) }, + ComponentType.ALIVE_BOX_CLOSE_CLOSE, null, drawableSet.getSkinParam(), null); - final LifeLine lifeLine = new LifeLine(box, comp.getPreferredWidth(stringBounder), drawableSet.getSkinParam() - .shadowing(p.getStereotype())); + final LifeLine lifeLine = new LifeLine(box, comp.getPreferredWidth(stringBounder), + drawableSet.getSkinParam().shadowing(p.getStereotype())); drawableSet.setLivingParticipantBox(p, new LivingParticipantBox(box, lifeLine)); this.freeX = box.getMaxX(stringBounder); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java index 0185494d1..d29b4ad29 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java @@ -85,8 +85,8 @@ class Step1Message extends Step1Abstract { final List noteOnMessages = message.getNoteOnMessages(); for (Note noteOnMessage : noteOnMessages) { final ISkinParam skinParam = noteOnMessage.getSkinParamBackcolored(drawingSet.getSkinParam()); - addNote(drawingSet.getSkin().createComponent(noteOnMessage.getUsedStyles(), - noteOnMessage.getNoteStyle().getNoteComponentType(), null, skinParam, noteOnMessage.getStrings())); + addNote(drawingSet.getSkin().createComponentNote(noteOnMessage.getUsedStyles(), + noteOnMessage.getNoteStyle().getNoteComponentType(), skinParam, noteOnMessage.getStrings())); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java index 04e51c1b2..278e5769e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java @@ -68,8 +68,8 @@ class Step1MessageExo extends Step1Abstract { final List noteOnMessages = message.getNoteOnMessages(); for (Note noteOnMessage : noteOnMessages) { final ISkinParam skinParam = noteOnMessage.getSkinParamBackcolored(drawingSet.getSkinParam()); - addNote(drawingSet.getSkin().createComponent(noteOnMessage.getUsedStyles(), - ComponentType.NOTE, null, skinParam, noteOnMessage.getStrings())); + addNote(drawingSet.getSkin().createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, skinParam, + noteOnMessage.getStrings())); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteBottom.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteBottom.java index 2a5841ebc..c09d06c03 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteBottom.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteBottom.java @@ -89,8 +89,8 @@ public class CommunicationTileNoteBottom extends AbstractTile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null, - noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings()); + final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam), + noteOnMessage.getStrings()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java index 467b42143..53750a8a9 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java @@ -87,8 +87,8 @@ public class CommunicationTileNoteLeft extends AbstractTile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null, - noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings()); + final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam), + noteOnMessage.getStrings()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java index dafd0c8da..ccb1e6bfa 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java @@ -91,8 +91,8 @@ public class CommunicationTileNoteRight extends AbstractTile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null, - noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings()); + final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam), + noteOnMessage.getStrings()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteTop.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteTop.java index e3df198e7..6f15e533b 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteTop.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteTop.java @@ -89,8 +89,8 @@ public class CommunicationTileNoteTop extends AbstractTile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(noteOnMessage.getUsedStyles(), ComponentType.NOTE, null, - noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings()); + final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam), + noteOnMessage.getStrings()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java index 16636c097..51465cb1f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteRight.java @@ -84,8 +84,8 @@ public class CommunicationTileSelfNoteRight extends AbstractTile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(null, ComponentType.NOTE, null, - noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getStrings()); + final Component comp = skin.createComponentNote(null, ComponentType.NOTE, noteOnMessage.getSkinParamBackcolored(skinParam), + noteOnMessage.getStrings()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java index 12bd884aa..fd9a01e7b 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java @@ -81,8 +81,8 @@ public class NoteTile extends AbstractTile implements Tile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()), - null, note.getSkinParamBackcolored(skinParam), note.getStrings()); + final Component comp = skin.createComponentNote(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()), + note.getSkinParamBackcolored(skinParam), note.getStrings(), note.getPosition()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/NotesTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/NotesTile.java index 30dbae01c..fddfbb7a6 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/NotesTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/NotesTile.java @@ -77,8 +77,8 @@ public class NotesTile extends AbstractTile implements Tile { } private Component getComponent(StringBounder stringBounder, Note note) { - final Component comp = skin.createComponent(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()), - null, note.getSkinParamBackcolored(skinParam), note.getStrings()); + final Component comp = skin.createComponentNote(note.getUsedStyles(), getNoteComponentType(note.getNoteStyle()), + note.getSkinParamBackcolored(skinParam), note.getStrings(), note.getPosition()); return comp; } diff --git a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java index 11723bc80..9c57f755a 100644 --- a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java +++ b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java @@ -69,6 +69,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent { private final UFont font; private final HColor fontColor; + private final HorizontalAlignment alignment; public AbstractTextualComponent(Style style, LineBreakStrategy maxMessageSize, CharSequence label, FontConfiguration font, HorizontalAlignment horizontalAlignment, int marginX1, int marginX2, int marginY, @@ -118,6 +119,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent { textBlock = this.display.create0(fc, horizontalAlignment, spriteContainer, maxMessageSize, CreoleMode.FULL, fontForStereotype, htmlColorForStereotype); } + this.alignment = horizontalAlignment; } protected HColorSet getIHtmlColorSet() { @@ -168,4 +170,8 @@ public abstract class AbstractTextualComponent extends AbstractComponent { return spriteContainer; } + public final HorizontalAlignment getHorizontalAlignment() { + return alignment; + } + } diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java index e207cf299..b3381d788 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java @@ -60,14 +60,16 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements private final double paddingY; private final SymbolContext symbolContext; private final double roundCorner; + private final HorizontalAlignment position; public ComponentRoseNote(Style style, SymbolContext symbolContext, FontConfiguration font, Display strings, double paddingX, double paddingY, ISkinSimple spriteContainer, double roundCorner, - HorizontalAlignment horizontalAlignment) { - super(style, spriteContainer.wrapWidth(), strings, font, horizontalAlignment, - horizontalAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, true, null, null); + HorizontalAlignment textAlignment, HorizontalAlignment position) { + super(style, spriteContainer.wrapWidth(), strings, font, textAlignment, + textAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, true, null, null); this.paddingX = paddingX; this.paddingY = paddingY; + this.position = position; if (UseStyle.useBetaStyle()) { this.symbolContext = style.getSymbolContext(spriteContainer.getThemeStyle(), getIHtmlColorSet()); this.roundCorner = style.value(PName.RoundCorner).asInt(); @@ -121,7 +123,15 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements ug.draw(Opale.getCorner(x2, roundCorner)); UGraphic ug2 = UGraphicStencil.create(ug, this, new UStroke()); - ug2 = ug2.apply(new UTranslate(getMarginX1() + diffX / 2, getMarginY())); + + if (position == HorizontalAlignment.LEFT) { + ug2 = ug2.apply(new UTranslate(getMarginX1(), getMarginY())); + } else if (position == HorizontalAlignment.RIGHT) { + ug2 = ug2.apply( + new UTranslate(area.getDimensionToUse().getWidth() - getTextWidth(stringBounder), getMarginY())); + } else { + ug2 = ug2.apply(new UTranslate(getMarginX1() + diffX / 2, getMarginY())); + } getTextBlock().drawU(ug2); diff --git a/src/net/sourceforge/plantuml/skin/rose/Rose.java b/src/net/sourceforge/plantuml/skin/rose/Rose.java index 0797ae9b3..b6d0c2095 100644 --- a/src/net/sourceforge/plantuml/skin/rose/Rose.java +++ b/src/net/sourceforge/plantuml/skin/rose/Rose.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.SkinParameter; import net.sourceforge.plantuml.graphic.SymbolContext; +import net.sourceforge.plantuml.sequencediagram.NotePosition; import net.sourceforge.plantuml.skin.ArrowComponent; import net.sourceforge.plantuml.skin.ArrowConfiguration; import net.sourceforge.plantuml.skin.ArrowDirection; @@ -90,8 +91,62 @@ public class Rose { return new FontConfiguration(skinParam, fontParam, null); } + public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param, + Display stringsToDisplay) { + checkRose(); + return createComponentNote(styles, type, param, stringsToDisplay, null); + } + + private void checkRose() { + // Quite ugly, but we want to ensure that TextSkin overrides those methods + if (this.getClass() != Rose.class) + throw new IllegalStateException("" + this.getClass()); + + } + + public Component createComponentNote(Style[] styles, ComponentType type, ISkinParam param, Display stringsToDisplay, + NotePosition notePosition) { + checkRose(); + final HorizontalAlignment textAlign; + final HorizontalAlignment position; + if (notePosition == NotePosition.OVER_SEVERAL) { + textAlign = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false, + HorizontalAlignment.LEFT); + if (textAlign == param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false, + HorizontalAlignment.CENTER)) + // Which means we use default + position = textAlign; + else + position = HorizontalAlignment.CENTER; + } else { + textAlign = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, false, null); + position = textAlign; + } + + final Stereotype stereotype = stringsToDisplay == null ? null : stringsToDisplay.getStereotypeIfAny(); + final double roundCorner = param.getRoundCorner(CornerParam.DEFAULT, null); + + if (type == ComponentType.NOTE) { + return new ComponentRoseNote(styles == null ? null : styles[0], + getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE), + stringsToDisplay, paddingX, paddingY, param, roundCorner, textAlign, position); + } + if (type == ComponentType.NOTE_HEXAGONAL) { + return new ComponentRoseNoteHexagonal(styles == null ? null : styles[0], + getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE), + stringsToDisplay, param, textAlign); + } + if (type == ComponentType.NOTE_BOX) { + return new ComponentRoseNoteBox(styles == null ? null : styles[0], + getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE), + stringsToDisplay, param, roundCorner, textAlign); + } + throw new UnsupportedOperationException(type.toString()); + } + public Component createComponent(Style[] styles, ComponentType type, ArrowConfiguration config, ISkinParam param, Display stringsToDisplay) { + checkRose(); final UFont fontGrouping = param.getFont(null, false, FontParam.SEQUENCE_GROUP); final Stereotype stereotype = stringsToDisplay == null ? null : stringsToDisplay.getStereotypeIfAny(); @@ -215,25 +270,13 @@ public class Rose { getFontColor(param, FontParam.DATABASE_STEREOTYPE)); } if (type == ComponentType.NOTE) { - final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, - false); - return new ComponentRoseNote(styles == null ? null : styles[0], - getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE), - stringsToDisplay, paddingX, paddingY, param, roundCorner, alignment); + throw new UnsupportedOperationException(); } if (type == ComponentType.NOTE_HEXAGONAL) { - final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, - false); - return new ComponentRoseNoteHexagonal(styles == null ? null : styles[0], - getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE), - stringsToDisplay, param, alignment); + throw new UnsupportedOperationException(); } if (type == ComponentType.NOTE_BOX) { - final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, - false); - return new ComponentRoseNoteBox(styles == null ? null : styles[0], - getSymbolContext(stereotype, param, ColorParam.noteBorder), getUFont2(param, FontParam.NOTE), - stringsToDisplay, param, roundCorner, alignment); + throw new UnsupportedOperationException(); } final FontConfiguration bigFont = getUFont2(param, FontParam.SEQUENCE_GROUP_HEADER); if (type == ComponentType.GROUPING_HEADER) { @@ -300,7 +343,7 @@ public class Rose { return new ComponentRoseReference(styles == null ? null : styles[0], styles == null ? null : styles[1], getUFont2(param, FontParam.SEQUENCE_REFERENCE), getSymbolContext(stereotype, param, ColorParam.sequenceReferenceBorder), bigFont, stringsToDisplay, - param.getHorizontalAlignment(AlignmentParam.sequenceReferenceAlignment, null, false), param, + param.getHorizontalAlignment(AlignmentParam.sequenceReferenceAlignment, null, false, null), param, getHtmlColor(param, stereotype, ColorParam.sequenceReferenceBackground)); } if (type == ComponentType.ENGLOBER) { @@ -309,15 +352,17 @@ public class Rose { getUFont2(param, FontParam.SEQUENCE_BOX), param, roundCorner); } - return null; + throw new UnsupportedOperationException(); } - public ComponentRoseNewpage createComponentNewPage(ISkinParam param) { + public Component createComponentNewPage(ISkinParam param) { + checkRose(); return new ComponentRoseNewpage(null, getHtmlColor(param, ColorParam.sequenceNewpageSeparator)); } public ArrowComponent createComponentArrow(Style[] styles, ArrowConfiguration config, ISkinParam param, Display stringsToDisplay) { + checkRose(); final HColor sequenceArrow = config.getColor() == null ? getHtmlColor(param, ColorParam.arrow) : config.getColor(); if (config.getArrowDirection() == ArrowDirection.SELF) { @@ -369,9 +414,9 @@ public class Rose { } } else { messageHorizontalAlignment = param.getHorizontalAlignment(AlignmentParam.sequenceMessageAlignment, - arrowDirection, config.isReverseDefine()); + arrowDirection, config.isReverseDefine(), null); textHorizontalAlignment = param.getHorizontalAlignment(AlignmentParam.sequenceMessageTextAlignment, - config.getArrowDirection(), false); + config.getArrowDirection(), false, null); } return new ComponentRoseArrow(styles == null ? null : styles[0], sequenceArrow, getUFont2(param, FontParam.ARROW), stringsToDisplay, config, messageHorizontalAlignment, param, diff --git a/src/net/sourceforge/plantuml/svek/Cluster.java b/src/net/sourceforge/plantuml/svek/Cluster.java index e2ed0ff8a..567b03102 100644 --- a/src/net/sourceforge/plantuml/svek/Cluster.java +++ b/src/net/sourceforge/plantuml/svek/Cluster.java @@ -383,7 +383,7 @@ public class Cluster implements Moveable { final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle, zstereo, minX, minY, maxX, maxY, stroke); decoration.drawU(ug, backColor, borderColor, shadowing, roundCorner, - skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false), + skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null), skinParam2.getStereotypeAlignment()); return; } @@ -781,7 +781,7 @@ public class Cluster implements Moveable { sblabel.append(">"); label = sblabel.toString(); final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, - null, false); + null, false, null); sb.append("labeljust=\"" + align.getGraphVizValue() + "\";"); } else { label = "\"\""; diff --git a/src/net/sourceforge/plantuml/svek/SvekLine.java b/src/net/sourceforge/plantuml/svek/SvekLine.java index 02e002643..24167aeb4 100644 --- a/src/net/sourceforge/plantuml/svek/SvekLine.java +++ b/src/net/sourceforge/plantuml/svek/SvekLine.java @@ -325,7 +325,7 @@ public class SvekLine implements Moveable, Hideable, GuideLine { private HorizontalAlignment getMessageTextAlignment(UmlDiagramType umlDiagramType, ISkinParam skinParam) { if (umlDiagramType == UmlDiagramType.STATE) { - return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false); + return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false, null); } return skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER); } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java index a8da759e0..bc91acc81 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageClass.java @@ -233,7 +233,9 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi public Ports getPorts(StringBounder stringBounder) { final Dimension2D dimHeader = header.calculateDimension(stringBounder); - return ((WithPorts) body).getPorts(stringBounder).translateY(dimHeader.getHeight()); + if (body instanceof WithPorts) + return ((WithPorts) body).getPorts(stringBounder).translateY(dimHeader.getHeight()); + return new Ports(); } private UStroke getStroke() { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java index 2c5712950..b36e53443 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java @@ -178,7 +178,7 @@ public class EntityImageEmptyPackage extends AbstractEntityImage { stereoBlock, 0, 0, widthTotal, heightTotal, stroke); final HorizontalAlignment horizontalAlignment = getSkinParam() - .getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false); + .getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null); final HorizontalAlignment stereotypeAlignment = getSkinParam().getStereotypeAlignment(); decoration.drawU(ug, back, borderColor, shadowing, roundCorner, horizontalAlignment, stereotypeAlignment); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java index ead7179a8..2e00152c1 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java @@ -40,6 +40,7 @@ import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.util.Objects; +import net.sourceforge.plantuml.AlignmentParam; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.Dimension2DDouble; @@ -129,7 +130,9 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { textBlock = new TextBlockEmpty(); } else { final FontConfiguration fc = new FontConfiguration(getSkinParam(), FontParam.NOTE, null); - textBlock = BodyFactory.create3(strings, FontParam.NOTE, getSkinParam(), HorizontalAlignment.LEFT, fc, + final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null, + false, null); + textBlock = BodyFactory.create3(strings, FontParam.NOTE, getSkinParam(), align, fc, getSkinParam().wrapWidth()); } } @@ -297,7 +300,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { return null; } - + private static double getOrthoDistance(Line2D.Double seg, Point2D pt) { if (isHorizontal(seg)) { return Math.abs(seg.getP1().getY() - pt.getY()); @@ -307,7 +310,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { } throw new IllegalArgumentException(); } - + private static boolean isHorizontal(Line2D.Double seg) { return seg.getP1().getY() == seg.getP2().getY(); } @@ -316,8 +319,6 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { return seg.getP1().getX() == seg.getP2().getX(); } - - public ShapeType getShapeType() { return ShapeType.RECTANGLE; } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java index 7181a430f..5427be73d 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNoteLink.java @@ -62,9 +62,9 @@ public class EntityImageNoteLink extends AbstractTextBlock implements IEntityIma public EntityImageNoteLink(Display note, Colors colors, ISkinParam skinParam, StyleBuilder styleBuilder) { final Rose skin = new Rose(); - comp = skin.createComponent( + comp = skin.createComponentNote( new Style[] { ComponentType.NOTE.getDefaultStyleDefinition().getMergedStyle(styleBuilder) }, - ComponentType.NOTE, null, colors.mute(skinParam), note); + ComponentType.NOTE, colors.mute(skinParam), note); } public Dimension2D calculateDimension(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java index b723da869..181f8f3c5 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java @@ -61,6 +61,9 @@ public class EntityImageStateBorder extends AbstractEntityImageBorder { } private boolean upPosition() { + if (parent == null) { + return false; + } final Point2D clusterCenter = parent.getClusterPosition().getPointCenter(); final SvekNode node = bibliotekon.getNode(getEntity()); return node.getMinY() < clusterCenter.getY(); diff --git a/src/net/sourceforge/plantuml/tim/Eater.java b/src/net/sourceforge/plantuml/tim/Eater.java index 0b1635987..d085fd379 100644 --- a/src/net/sourceforge/plantuml/tim/Eater.java +++ b/src/net/sourceforge/plantuml/tim/Eater.java @@ -77,8 +77,7 @@ public abstract class Eater { return result; } - final protected TValue eatExpression(TContext context, TMemory memory) - throws EaterException, EaterExceptionLocated { + final public TValue eatExpression(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated { if (peekChar() == '{') { String data = eatAllToEnd(); // System.err.println("data=" + data); diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index 6d880fde8..02f81bbaf 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -86,6 +86,7 @@ import net.sourceforge.plantuml.tim.stdlib.CallUserFunction; import net.sourceforge.plantuml.tim.stdlib.Darken; import net.sourceforge.plantuml.tim.stdlib.DateFunction; import net.sourceforge.plantuml.tim.stdlib.Dirpath; +import net.sourceforge.plantuml.tim.stdlib.Eval; import net.sourceforge.plantuml.tim.stdlib.Feature; import net.sourceforge.plantuml.tim.stdlib.FileExists; import net.sourceforge.plantuml.tim.stdlib.Filename; @@ -102,8 +103,8 @@ import net.sourceforge.plantuml.tim.stdlib.LogicalNot; import net.sourceforge.plantuml.tim.stdlib.Lower; import net.sourceforge.plantuml.tim.stdlib.Newline; import net.sourceforge.plantuml.tim.stdlib.RetrieveProcedure; -import net.sourceforge.plantuml.tim.stdlib.ReverseHsluvColor; import net.sourceforge.plantuml.tim.stdlib.ReverseColor; +import net.sourceforge.plantuml.tim.stdlib.ReverseHsluvColor; import net.sourceforge.plantuml.tim.stdlib.SetVariableValue; import net.sourceforge.plantuml.tim.stdlib.StringFunction; import net.sourceforge.plantuml.tim.stdlib.Strlen; @@ -164,6 +165,7 @@ public class TContext { functionsSet.addFunction(new IsLight()); functionsSet.addFunction(new ReverseHsluvColor()); functionsSet.addFunction(new ReverseColor()); + functionsSet.addFunction(new Eval()); // %standard_exists_function // %str_replace // !exit diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Eval.java b/src/net/sourceforge/plantuml/tim/stdlib/Eval.java new file mode 100644 index 000000000..9e0d2d3d7 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/Eval.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.tim.stdlib; + +import java.util.List; +import 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.StringEater; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; + +public class Eval extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%eval", 1); + } + + public boolean canCover(int nbArg, Set namedArgument) { + return nbArg == 1; + } + + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final String exp = values.get(0).toString(); + final StringEater eater = new StringEater(exp); + final TValue value = eater.eatExpression(context, memory); + return TValue.fromInt(value.toInt()); + } +} diff --git a/src/net/sourceforge/plantuml/version/License.java b/src/net/sourceforge/plantuml/version/License.java index d240e638e..d2f5a5134 100644 --- a/src/net/sourceforge/plantuml/version/License.java +++ b/src/net/sourceforge/plantuml/version/License.java @@ -196,10 +196,8 @@ public enum License { text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public"); text.add("License for more details."); text.add(" "); - text.add("You should have received a copy of the GNU General Public"); - text.add("License along with this library; if not, write to the Free Software"); - text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,"); - text.add("USA."); + text.add("You should have received a copy of the GNU General Public License"); + text.add("along with this library. If not, see ."); text.add(" "); addSupplementary(licenseInfo, text); text.add("the GPL license."); @@ -224,10 +222,8 @@ public enum License { text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public"); text.add("License for more details."); text.add(" "); - text.add("You should have received a copy of the GNU General Public"); - text.add("License along with this library; if not, write to the Free Software"); - text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,"); - text.add("USA."); + text.add("You should have received a copy of the GNU General Public License"); + text.add("along with this library. If not, see ."); text.add(" "); addSupplementary(licenseInfo, text); text.add("the GPL license."); @@ -252,10 +248,8 @@ public enum License { text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public"); text.add("License for more details."); text.add(" "); - text.add("You should have received a copy of the GNU Lesser General Public"); - text.add("License along with this library; if not, write to the Free Software"); - text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,"); - text.add("USA."); + text.add("You should have received a copy of the GNU Lesser General Public License"); + text.add("along with this library. If not, see ."); text.add(" "); addSupplementary(licenseInfo, text); text.add("the LGPL license."); @@ -369,10 +363,8 @@ public enum License { h.add(" * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public"); h.add(" * License for more details."); h.add(" *"); - h.add(" * You should have received a copy of the GNU Lesser General Public"); - h.add(" * License along with this library; if not, write to the Free Software"); - h.add(" * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,"); - h.add(" * USA."); + h.add(" * You should have received a copy of the GNU General Public License"); + h.add(" * along with this library. If not, see ."); h.add(" *"); } else if (this == License.GPLV2) { h.add(" * PlantUML is free software; you can redistribute it and/or modify it"); @@ -385,10 +377,8 @@ public enum License { h.add(" * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public"); h.add(" * License for more details."); h.add(" *"); - h.add(" * You should have received a copy of the GNU General Public"); - h.add(" * License along with this library; if not, write to the Free Software"); - h.add(" * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,"); - h.add(" * USA."); + h.add(" * You should have received a copy of the GNU General Public License"); + h.add(" * along with this library. If not, see ."); h.add(" *"); } else if (this == License.APACHE) { h.add(" * Licensed under the Apache License, Version 2.0 (the \"License\");"); diff --git a/src/net/sourceforge/plantuml/version/LicenseInfo.java b/src/net/sourceforge/plantuml/version/LicenseInfo.java index 9eb0a8c98..3762257b6 100644 --- a/src/net/sourceforge/plantuml/version/LicenseInfo.java +++ b/src/net/sourceforge/plantuml/version/LicenseInfo.java @@ -194,6 +194,8 @@ public class LicenseInfo { final String classpath = System.getProperty("java.class.path"); String[] classpathEntries = classpath.split(SFile.pathSeparator); for (String s : classpathEntries) { + if (s == null) + continue; SFile dir = new SFile(s); if (dir.isFile()) { dir = dir.getParentFile(); diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index caf460870..9ca8b0f37 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -44,7 +44,7 @@ public class Version { private static final int MAJOR_SEPARATOR = 1000000; public static int version() { - return 1202107; + return 1202108; } public static int versionPatched() { @@ -93,7 +93,7 @@ public class Version { } public static long compileTime() { - return 1621773607941L; + return 1624695659217L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.java b/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.java new file mode 100644 index 000000000..34ab1b72f --- /dev/null +++ b/src/net/sourceforge/plantuml/wbs/CommandWBSItemMultiline.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 + * + * + */ +package net.sourceforge.plantuml.wbs; + +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.BlocLines; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines2; +import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.MyPattern; +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.mindmap.IdeaShape; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException; + +public class CommandWBSItemMultiline extends CommandMultilines2 { + + public CommandWBSItemMultiline() { + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandWBSItemMultiline.class.getName(), RegexLeaf.start(), // + new RegexLeaf("TYPE", "([ \t]*[*+-]+)"), // + new RegexOptional(new RegexLeaf("BACKCOLOR", "\\[(#\\w+)\\]")), // + new RegexLeaf("SHAPE", "(_)?"), // + new RegexLeaf(":"), // + new RegexLeaf("DATA", "(.*)"), // + RegexLeaf.end()); + } + + @Override + public String getPatternEnd() { + return "^(.*);(?:\\s*\\<\\<(.+)\\>\\>)?$"; + } + + static IRegex getRegexConcatOld() { + return RegexConcat.build(CommandWBSItemMultiline.class.getName(), RegexLeaf.start(), // + new RegexLeaf("TYPE", "([ \t]*[*+-]+)"), // + new RegexOptional(new RegexLeaf("BACKCOLOR", "\\[(#\\w+)\\]")), // + new RegexLeaf("SHAPE", "(_)?"), // + new RegexLeaf("DIRECTION", "([<>])?"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("LABEL", "([^%s].*)"), RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeNow(WBSDiagram diagram, BlocLines lines) throws NoSuchColorException { + final RegexResult line0 = getStartingPattern().matcher(lines.getFirst().getTrimmed().getString()); + + final List lineLast = StringUtils.getSplit(MyPattern.cmpile(getPatternEnd()), + lines.getLast().getString()); + lines = lines.removeStartingAndEnding(line0.get("DATA", 0), 1); + + final String stereotype = lineLast.get(1); + if (stereotype != null) { + lines = lines.overrideLastLine(lineLast.get(0)); + } + + final String type = line0.get("TYPE", 0); + final String stringColor = line0.get("BACKCOLOR", 0); + HColor backColor = null; + if (stringColor != null) { + backColor = diagram.getSkinParam().getIHtmlColorSet().getColor(diagram.getSkinParam().getThemeStyle(), + stringColor); + } + + Direction dir = Direction.RIGHT; + + return diagram.addIdea(backColor, diagram.getSmartLevel(type), lines.toDisplay(), stereotype, dir, + IdeaShape.fromDesc(line0.get("SHAPE", 0))); + + } + +} diff --git a/src/net/sourceforge/plantuml/wbs/WBSDiagram.java b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java index f4b69199a..eec78117c 100644 --- a/src/net/sourceforge/plantuml/wbs/WBSDiagram.java +++ b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java @@ -119,21 +119,27 @@ public class WBSDiagram extends UmlDiagram { public CommandExecutionResult addIdea(HColor backColor, int level, String label, Direction direction, IdeaShape shape) { + final Matcher2 m = patternStereotype.matcher(label); + String stereotype = null; + if (m.matches()) { + label = m.group(1); + stereotype = m.group(2); + } + final Display display = Display.getWithNewlines(label); + return addIdea(backColor, level, display, stereotype, direction, shape); + } + + public CommandExecutionResult addIdea(HColor backColor, int level, Display display, String stereotype, + Direction direction, IdeaShape shape) { try { - final Matcher2 m = patternStereotype.matcher(label); - String stereotype = null; - if (m.matches()) { - label = m.group(1); - stereotype = m.group(2); - } if (level == 0) { if (root != null) { return CommandExecutionResult.error("Error 44"); } - initRoot(backColor, label, stereotype, shape); + initRoot(backColor, display, stereotype, shape); return CommandExecutionResult.ok(); } - return add(backColor, level, label, stereotype, direction, shape); + return add(backColor, level, display, stereotype, direction, shape); } catch (NoStyleAvailableException e) { // e.printStackTrace(); return CommandExecutionResult.error("General failure: no style available."); @@ -144,9 +150,8 @@ public class WBSDiagram extends UmlDiagram { private WElement last; private String first; - private void initRoot(HColor backColor, String label, String stereotype, IdeaShape shape) { - root = new WElement(backColor, Display.getWithNewlines(label), stereotype, - getSkinParam().getCurrentStyleBuilder(), shape); + private void initRoot(HColor backColor, Display display, String stereotype, IdeaShape shape) { + root = new WElement(backColor, display, stereotype, getSkinParam().getCurrentStyleBuilder(), shape); last = root; } @@ -180,20 +185,19 @@ public class WBSDiagram extends UmlDiagram { throw new UnsupportedOperationException("type=<" + type + ">[" + first + "]"); } - private CommandExecutionResult add(HColor backColor, int level, String label, String stereotype, + private CommandExecutionResult add(HColor backColor, int level, Display display, String stereotype, Direction direction, IdeaShape shape) { try { if (level == last.getLevel() + 1) { - final WElement newIdea = last.createElement(backColor, level, Display.getWithNewlines(label), - stereotype, direction, shape, getSkinParam().getCurrentStyleBuilder()); + final WElement newIdea = last.createElement(backColor, level, display, stereotype, direction, shape, + getSkinParam().getCurrentStyleBuilder()); last = newIdea; return CommandExecutionResult.ok(); } if (level <= last.getLevel()) { final int diff = last.getLevel() - level + 1; - final WElement newIdea = getParentOfLast(diff).createElement(backColor, level, - Display.getWithNewlines(label), stereotype, direction, shape, - getSkinParam().getCurrentStyleBuilder()); + final WElement newIdea = getParentOfLast(diff).createElement(backColor, level, display, stereotype, + direction, shape, getSkinParam().getCurrentStyleBuilder()); last = newIdea; return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java b/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java index 40bee270f..4c4311678 100644 --- a/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java +++ b/src/net/sourceforge/plantuml/wbs/WBSDiagramFactory.java @@ -56,6 +56,7 @@ public class WBSDiagramFactory extends PSystemCommandFactory { final List cmds = new ArrayList<>(); addCommonCommands1(cmds); cmds.add(new CommandWBSItem()); + cmds.add(new CommandWBSItemMultiline()); return cmds; } diff --git a/test/net/sourceforge/plantuml/math/Math01Test.java b/test/net/sourceforge/plantuml/math/Math01Test.java new file mode 100644 index 000000000..64865c751 --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math01Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math01Test { + + private final String math = "f(x)"; + private final String expected = "{f{{\\left({x}\\right)}}}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math02Test.java b/test/net/sourceforge/plantuml/math/Math02Test.java new file mode 100644 index 000000000..739385d73 --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math02Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math02Test { + + private final String math = "x"; + private final String expected = "{x}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math03Test.java b/test/net/sourceforge/plantuml/math/Math03Test.java new file mode 100644 index 000000000..38f0b3afc --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math03Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math03Test { + + private final String math = "color(red)(f(t))=color(blue)((a_0)/2 + sum_(n=1)^ooa_ncos((npit)/L)+sum_(n=1)^oo b_n\\ sin((npit)/L))"; + private final String expected = "{\\textcolor{red}{{f{{\\left({t}\\right)}}}}}={\\textcolor{blue}{\\frac{{{a}_{{0}}}}{{2}}+{\\sum_{{{n}={1}}}^{\\infty}}{a}_{{n}}{\\cos{{\\left(\\frac{{{n}\\pi{t}}}{{L}}\\right)}}}+{\\sum_{{{n}={1}}}^{\\infty}}{b}_{{n}}\\ {\\sin{{\\left(\\frac{{{n}\\pi{t}}}{{L}}\\right)}}}}}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math04Test.java b/test/net/sourceforge/plantuml/math/Math04Test.java new file mode 100644 index 000000000..f55cba6f4 --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math04Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math04Test { + + private final String math = "abs(x)"; + private final String expected = "{\\left|{{x}}\\right|}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math05Test.java b/test/net/sourceforge/plantuml/math/Math05Test.java new file mode 100644 index 000000000..f6e4ffebf --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math05Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math05Test { + + private final String math = "y=ceil(x)"; + private final String expected = "{y}={\\left\\lceil{{x}}\\right\\rceil}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math06Test.java b/test/net/sourceforge/plantuml/math/Math06Test.java new file mode 100644 index 000000000..fb9efd85d --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math06Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math06Test { + + private final String math = "f(t)=(a_0)/2 + sum_(n=1)^ooa_ncos((npit)/L)+sum_(n=1)^oo b_n\\ sin((npit)/L)"; + private final String expected = "{f{{\\left({t}\\right)}}}=\\frac{{{a}_{{0}}}}{{2}}+{\\sum_{{{n}={1}}}^{\\infty}}{a}_{{n}}{\\cos{{\\left(\\frac{{{n}\\pi{t}}}{{L}}\\right)}}}+{\\sum_{{{n}={1}}}^{\\infty}}{b}_{{n}}\\ {\\sin{{\\left(\\frac{{{n}\\pi{t}}}{{L}}\\right)}}}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math07Test.java b/test/net/sourceforge/plantuml/math/Math07Test.java new file mode 100644 index 000000000..317632937 --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math07Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math07Test { + + private final String math = "[[a,b],[c,d]]"; + private final String expected = "{\\left[\\begin{matrix}{a}&{b}\\\\{c}&{d}\\end{matrix}\\right]}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math08Test.java b/test/net/sourceforge/plantuml/math/Math08Test.java new file mode 100644 index 000000000..dd18e9a02 --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math08Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math08Test { + + private final String math = "color(red)(x)"; + private final String expected = "{\\textcolor{red}{{x}}}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/test/net/sourceforge/plantuml/math/Math09Test.java b/test/net/sourceforge/plantuml/math/Math09Test.java new file mode 100644 index 000000000..6997a7f8b --- /dev/null +++ b/test/net/sourceforge/plantuml/math/Math09Test.java @@ -0,0 +1,18 @@ +package net.sourceforge.plantuml.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class Math09Test { + + private final String math = "color(red)(t)=color(blue)(x)"; + private final String expected = "{\\textcolor{red}{{t}}}={\\textcolor{blue}{{x}}}"; + + @Test + public void testJava() { + final String res = new ASCIIMathTeXImg().getTeX(math); + assertEquals(expected, res); + } + +} diff --git a/themes/puml-theme-aws-orange.puml b/themes/puml-theme-aws-orange.puml index f9e01b545..a44fe83ef 100644 --- a/themes/puml-theme-aws-orange.puml +++ b/themes/puml-theme-aws-orange.puml @@ -531,4 +531,4 @@ skinparam stack { $primary_scheme() } -!endsub +!endsub \ No newline at end of file