mirror of
https://github.com/octoleo/plantuml.git
synced 2024-11-22 13:05:09 +00:00
EBNF improvements
This commit is contained in:
parent
ee3037db80
commit
ecf66ff391
@ -39,21 +39,61 @@ import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
|
||||
enum CornerType {
|
||||
NW, NE, SE, SW;
|
||||
}
|
||||
|
||||
public class CornerCurved implements UDrawable {
|
||||
|
||||
private final double delta;
|
||||
private final CornerType type;
|
||||
|
||||
public CornerCurved(double delta) {
|
||||
private CornerCurved(CornerType type, double delta) {
|
||||
this.delta = delta;
|
||||
this.type = type;
|
||||
if (delta <= 0)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public static UDrawable createSW(double delta) {
|
||||
return new CornerCurved(CornerType.SW, delta);
|
||||
}
|
||||
|
||||
public static UDrawable createSE(double delta) {
|
||||
return new CornerCurved(CornerType.SE, delta);
|
||||
}
|
||||
|
||||
public static UDrawable createNE(double delta) {
|
||||
return new CornerCurved(CornerType.NE, delta);
|
||||
}
|
||||
|
||||
public static UDrawable createNW(double delta) {
|
||||
return new CornerCurved(CornerType.NW, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, -Math.abs(delta));
|
||||
|
||||
final double a = delta / 4;
|
||||
path.cubicTo(0, -Math.abs(a), a, 0, delta, 0);
|
||||
|
||||
switch (type) {
|
||||
case SW:
|
||||
path.moveTo(0, -delta);
|
||||
path.cubicTo(0, -a, a, 0, delta, 0);
|
||||
break;
|
||||
case SE:
|
||||
path.moveTo(0, -delta);
|
||||
path.cubicTo(0, -a, -a, 0, -delta, 0);
|
||||
break;
|
||||
case NE:
|
||||
path.moveTo(-delta, 0);
|
||||
path.cubicTo(-a, 0, 0, a, 0, delta);
|
||||
break;
|
||||
case NW:
|
||||
path.moveTo(0, delta);
|
||||
path.cubicTo(0, a, a, 0, delta, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
ug.draw(path);
|
||||
}
|
||||
|
@ -42,4 +42,6 @@ public interface ETile extends TextBlock {
|
||||
|
||||
public double linePos(StringBounder stringBounder);
|
||||
|
||||
public void push(ETile tile);
|
||||
|
||||
}
|
||||
|
@ -38,115 +38,89 @@ package net.sourceforge.plantuml.ebnf;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.style.SName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
import net.sourceforge.plantuml.style.StyleBuilder;
|
||||
import net.sourceforge.plantuml.style.StyleSignatureBasic;
|
||||
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
|
||||
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.HColors;
|
||||
|
||||
public class Alternation extends AbstractTextBlock implements TextBlockBackcolored, ETile {
|
||||
public class ETileAlternation extends AbstractTextBlock implements ETile {
|
||||
|
||||
private final List<String> values = new ArrayList<>();
|
||||
private final StyleBuilder styleBuilder;
|
||||
private final HColorSet colorSet;
|
||||
private final List<ETile> tiles = new ArrayList<>();
|
||||
private final double marginx = 12;
|
||||
|
||||
public Alternation(ISkinParam skinParam) {
|
||||
this.styleBuilder = skinParam.getCurrentStyleBuilder();
|
||||
this.colorSet = skinParam.getIHtmlColorSet();
|
||||
}
|
||||
|
||||
public void alternation(Token token) {
|
||||
values.add(0, token.getData());
|
||||
@Override
|
||||
public void push(ETile tile) {
|
||||
tiles.add(0, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double linePos(StringBounder stringBounder) {
|
||||
final Style style = getStyleSignature().getMergedStyle(styleBuilder);
|
||||
final FontConfiguration fc = style.getFontConfiguration(colorSet);
|
||||
final ETile tile = new ETileBox(values.get(0), fc);
|
||||
return tile.linePos(stringBounder);
|
||||
return tiles.get(0).linePos(stringBounder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
ug = ug.apply(HColors.BLACK);
|
||||
final Style style = getStyleSignature().getMergedStyle(styleBuilder);
|
||||
final FontConfiguration fc = style.getFontConfiguration(colorSet);
|
||||
double y = 0;
|
||||
double lastLinePos = 0;
|
||||
|
||||
final double b = 30 - 16;
|
||||
final double a = b - 8;
|
||||
final double c = b + 8;
|
||||
final double a = 0;
|
||||
final double b = a + marginx;
|
||||
final double c = b + marginx;
|
||||
|
||||
final XDimension2D fullDim = calculateDimension(stringBounder);
|
||||
|
||||
final double q = fullDim.getWidth() - 14;
|
||||
final double p = q - 8;
|
||||
final double r = q + 8;
|
||||
final double r = fullDim.getWidth();
|
||||
final double q = r - marginx;
|
||||
final double p = q - marginx;
|
||||
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
final String value = values.get(i);
|
||||
final ETile tile = new ETileBox(value, fc);
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
final ETile tile = tiles.get(i);
|
||||
final XDimension2D dim = tile.calculateDimension(stringBounder);
|
||||
lastLinePos = y + tile.linePos(stringBounder);
|
||||
tile.drawU(ug.apply(new UTranslate(30, y)));
|
||||
tile.drawU(ug.apply(new UTranslate(c, y)));
|
||||
|
||||
if (i == 0) {
|
||||
drawHline(ug, lastLinePos, 0, 30);
|
||||
drawHline(ug, lastLinePos, 30 + dim.getWidth(), fullDim.getWidth());
|
||||
} else if (i > 0 && i < values.size() - 1) {
|
||||
drawHline(ug, lastLinePos, c, 30);
|
||||
new CornerCurved(8).drawU(ug.apply(new UTranslate(b, lastLinePos)));
|
||||
drawHline(ug, lastLinePos, 30 + dim.getWidth(), p);
|
||||
new CornerCurved(-8).drawU(ug.apply(new UTranslate(q, lastLinePos)));
|
||||
|
||||
} else if (i == values.size() - 1) {
|
||||
drawHline(ug, lastLinePos, c, 30);
|
||||
drawHline(ug, lastLinePos, 30 + dim.getWidth(), p);
|
||||
ETileConcatenation.drawHline(ug, lastLinePos, a, c);
|
||||
ETileConcatenation.drawHline(ug, lastLinePos, c + dim.getWidth(), r);
|
||||
} else if (i > 0 && i < tiles.size() - 1) {
|
||||
CornerCurved.createSW(marginx).drawU(ug.apply(new UTranslate(b, lastLinePos)));
|
||||
ETileConcatenation.drawHline(ug, lastLinePos, c + dim.getWidth(), p);
|
||||
CornerCurved.createSE(marginx).drawU(ug.apply(new UTranslate(q, lastLinePos)));
|
||||
} else if (i == tiles.size() - 1) {
|
||||
ETileConcatenation.drawHline(ug, lastLinePos, c + dim.getWidth(), p);
|
||||
|
||||
}
|
||||
y += dim.getHeight() + 10;
|
||||
}
|
||||
final double linePos = linePos(stringBounder);
|
||||
|
||||
final HLineCurved hlineIn = new HLineCurved(lastLinePos - linePos, 8);
|
||||
final VLineCurved hlineIn = new VLineCurved(lastLinePos - linePos, marginx, CornerCurved.createNE(marginx),
|
||||
CornerCurved.createSW(marginx));
|
||||
hlineIn.drawU(ug.apply(new UTranslate(b, linePos)));
|
||||
|
||||
final HLineCurved hlineOut = new HLineCurved(lastLinePos - linePos, -8);
|
||||
final VLineCurved hlineOut = new VLineCurved(lastLinePos - linePos, marginx, CornerCurved.createNW(marginx),
|
||||
CornerCurved.createSE(marginx));
|
||||
hlineOut.drawU(ug.apply(new UTranslate(q, linePos)));
|
||||
|
||||
}
|
||||
|
||||
private void drawHline(UGraphic ug, double y, double x1, double x2) {
|
||||
ug.apply(new UTranslate(x1, y)).draw(ULine.hline(x2 - x1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
final Style style = getStyleSignature().getMergedStyle(styleBuilder);
|
||||
final FontConfiguration fc = style.getFontConfiguration(colorSet);
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
for (String value : values) {
|
||||
final ETile tile = new ETileBox(value, fc);
|
||||
for (ETile tile : tiles) {
|
||||
final XDimension2D dim = tile.calculateDimension(stringBounder);
|
||||
height += dim.getHeight() + 10;
|
||||
height += dim.getHeight();
|
||||
height += 10;
|
||||
width = Math.max(width, dim.getWidth());
|
||||
}
|
||||
width += 60;
|
||||
width += 2 * 2 * marginx;
|
||||
return new XDimension2D(width, height);
|
||||
}
|
||||
|
||||
@ -154,9 +128,4 @@ public class Alternation extends AbstractTextBlock implements TextBlockBackcolor
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, SName.activityDiagram, SName.activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HColor getBackcolor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -39,23 +39,32 @@ import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.style.PName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.URectangle;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.UText;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColors;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
|
||||
|
||||
public class ETileBox extends AbstractTextBlock implements ETile {
|
||||
|
||||
private final String value;
|
||||
private final FontConfiguration fc;
|
||||
private final Style style;
|
||||
private final UText utext;
|
||||
private final HColorSet colorSet;
|
||||
private final Symbol symbol;
|
||||
|
||||
public ETileBox(String value, FontConfiguration fc) {
|
||||
public ETileBox(String value, Symbol symbol, FontConfiguration fc, Style style, HColorSet colorSet) {
|
||||
this.symbol = symbol;
|
||||
this.value = value;
|
||||
this.fc = fc;
|
||||
this.utext = new UText(value, fc);
|
||||
this.style = style;
|
||||
this.colorSet = colorSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,8 +80,17 @@ public class ETileBox extends AbstractTextBlock implements ETile {
|
||||
public void drawU(UGraphic ug) {
|
||||
final XDimension2D dim = calculateDimension(ug.getStringBounder());
|
||||
final XDimension2D dimText = getTextDim(ug.getStringBounder());
|
||||
final URectangle rect = new URectangle(dim).rounded(10);
|
||||
ug.apply(HColors.BLACK).apply(new UStroke(1.5)).draw(rect);
|
||||
final HColor lineColor = style.value(PName.LineColor).asColor(colorSet);
|
||||
final HColor backgroundColor = style.value(PName.BackGroundColor).asColor(colorSet);
|
||||
|
||||
if (symbol == Symbol.TERMINAL_STRING1 || symbol == Symbol.TERMINAL_STRING2) {
|
||||
final URectangle rect = new URectangle(dim);
|
||||
ug.apply(lineColor).apply(new UStroke(0.5)).draw(rect);
|
||||
} else {
|
||||
final URectangle rect = new URectangle(dim).rounded(10);
|
||||
ug.apply(lineColor).apply(backgroundColor.bg()).apply(new UStroke(1.5)).draw(rect);
|
||||
}
|
||||
|
||||
ug.apply(new UTranslate(5, 5 + dimText.getHeight() - utext.getDescent(ug.getStringBounder()))).draw(utext);
|
||||
}
|
||||
|
||||
@ -82,4 +100,9 @@ public class ETileBox extends AbstractTextBlock implements ETile {
|
||||
return height / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(ETile tile) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
114
src/net/sourceforge/plantuml/ebnf/ETileConcatenation.java
Normal file
114
src/net/sourceforge/plantuml/ebnf/ETileConcatenation.java
Normal file
@ -0,0 +1,114 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColors;
|
||||
|
||||
public class ETileConcatenation extends AbstractTextBlock implements ETile {
|
||||
|
||||
private final double marginx = 16;
|
||||
private final List<ETile> tiles = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void push(ETile tile) {
|
||||
tiles.add(0, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double linePos(StringBounder stringBounder) {
|
||||
double result = 0;
|
||||
|
||||
for (ETile tile : tiles)
|
||||
result = Math.max(result, tile.linePos(stringBounder));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
ug = ug.apply(HColors.BLACK);
|
||||
|
||||
final double fullLinePos = linePos(stringBounder);
|
||||
double x = 0;
|
||||
drawHline(ug, fullLinePos, 0, x);
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
final ETile tile = tiles.get(i);
|
||||
final double linePos = tile.linePos(stringBounder);
|
||||
tile.drawU(ug.apply(new UTranslate(x, fullLinePos - linePos)));
|
||||
x += tile.calculateDimension(stringBounder).getWidth();
|
||||
if (i != tiles.size() - 1) {
|
||||
drawHline(ug, fullLinePos, x, x + marginx);
|
||||
x += marginx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void drawHline(UGraphic ug, double y, double x1, double x2) {
|
||||
ug.apply(new UTranslate(x1, y)).draw(ULine.hline(x2 - x1));
|
||||
}
|
||||
|
||||
public static void drawVline(UGraphic ug, double x, double y1, double y2) {
|
||||
ug.apply(new UTranslate(x, y1)).draw(ULine.vline(y2 - y1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
final ETile tile = tiles.get(i);
|
||||
final XDimension2D dim = tile.calculateDimension(stringBounder);
|
||||
height = Math.max(height, dim.getHeight());
|
||||
width += dim.getWidth();
|
||||
if (i != tiles.size() - 1)
|
||||
width += marginx;
|
||||
}
|
||||
return new XDimension2D(width, height);
|
||||
}
|
||||
|
||||
}
|
92
src/net/sourceforge/plantuml/ebnf/ETileOptional.java
Normal file
92
src/net/sourceforge/plantuml/ebnf/ETileOptional.java
Normal file
@ -0,0 +1,92 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColors;
|
||||
|
||||
public class ETileOptional extends AbstractTextBlock implements ETile {
|
||||
|
||||
private final double posLineTop = 21;
|
||||
private final double deltax = 15;
|
||||
private final double deltay = 24;
|
||||
private final ETile orig;
|
||||
|
||||
public ETileOptional(ETile orig) {
|
||||
this.orig = orig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return XDimension2D.delta(orig.calculateDimension(stringBounder), 2 * deltax, deltay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final XDimension2D fullDim = calculateDimension(ug.getStringBounder());
|
||||
ug = ug.apply(HColors.BLACK);
|
||||
final double linePos = linePos(ug.getStringBounder());
|
||||
CornerCurved.createSE(8).drawU(ug.apply(new UTranslate(8, linePos)));
|
||||
ETileConcatenation.drawVline(ug, 8, linePos - posLineTop + 8, linePos - 8);
|
||||
CornerCurved.createNW(8).drawU(ug.apply(new UTranslate(8, linePos - posLineTop)));
|
||||
|
||||
ETileConcatenation.drawHline(ug, linePos - posLineTop, deltax, fullDim.getWidth() - deltax);
|
||||
|
||||
CornerCurved.createSW(8).drawU(ug.apply(new UTranslate(fullDim.getWidth() - 8, linePos)));
|
||||
ETileConcatenation.drawVline(ug, fullDim.getWidth() - 8, linePos - posLineTop + 8, linePos - 8);
|
||||
CornerCurved.createNE(8).drawU(ug.apply(new UTranslate(fullDim.getWidth() - 8, linePos - posLineTop)));
|
||||
|
||||
ETileConcatenation.drawHline(ug, linePos, 0, deltax);
|
||||
ETileConcatenation.drawHline(ug, linePos, fullDim.getWidth() - deltax, fullDim.getWidth());
|
||||
|
||||
orig.drawU(ug.apply(new UTranslate(deltax, deltay)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double linePos(StringBounder stringBounder) {
|
||||
return deltay + orig.linePos(stringBounder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(ETile tile) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
97
src/net/sourceforge/plantuml/ebnf/ETileRepetition.java
Normal file
97
src/net/sourceforge/plantuml/ebnf/ETileRepetition.java
Normal file
@ -0,0 +1,97 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColors;
|
||||
|
||||
public class ETileRepetition extends AbstractTextBlock implements ETile {
|
||||
|
||||
private final double deltax = 20;
|
||||
private final double deltay = 10;
|
||||
private final ETile orig;
|
||||
|
||||
public ETileRepetition(ETile orig) {
|
||||
this.orig = orig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return XDimension2D.delta(orig.calculateDimension(stringBounder), 2 * deltax, deltay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final XDimension2D fullDim = calculateDimension(ug.getStringBounder());
|
||||
ug = ug.apply(HColors.BLACK);
|
||||
final double linePos = linePos(ug.getStringBounder());
|
||||
|
||||
final double posA = 7;
|
||||
final double posB = fullDim.getWidth() - 7;
|
||||
|
||||
final double corner = 12;
|
||||
|
||||
CornerCurved.createNW(corner).drawU(ug.apply(new UTranslate(posA, linePos)));
|
||||
ETileConcatenation.drawVline(ug, posA, linePos + corner, fullDim.getHeight() - 1 - corner);
|
||||
CornerCurved.createSW(corner).drawU(ug.apply(new UTranslate(posA, fullDim.getHeight() - 1)));
|
||||
|
||||
CornerCurved.createNE(corner).drawU(ug.apply(new UTranslate(posB, linePos)));
|
||||
ETileConcatenation.drawVline(ug, posB, linePos + corner, fullDim.getHeight() - 1 - corner);
|
||||
CornerCurved.createSE(corner).drawU(ug.apply(new UTranslate(posB, fullDim.getHeight() - 1)));
|
||||
|
||||
ETileConcatenation.drawHline(ug, fullDim.getHeight() - 1, posA + corner, posB - corner);
|
||||
|
||||
ETileConcatenation.drawHline(ug, linePos, 0, deltax);
|
||||
ETileConcatenation.drawHline(ug, linePos, fullDim.getWidth() - deltax, fullDim.getWidth());
|
||||
|
||||
orig.drawU(ug.apply(new UTranslate(deltax, 0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double linePos(StringBounder stringBounder) {
|
||||
return orig.linePos(stringBounder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(ETile tile) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
85
src/net/sourceforge/plantuml/ebnf/ETileWithCircles.java
Normal file
85
src/net/sourceforge/plantuml/ebnf/ETileWithCircles.java
Normal file
@ -0,0 +1,85 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UEllipse;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColors;
|
||||
|
||||
public class ETileWithCircles extends AbstractTextBlock implements ETile {
|
||||
|
||||
private static final double SIZE = 8;
|
||||
|
||||
private final double deltax = 15;
|
||||
private final ETile orig;
|
||||
|
||||
public ETileWithCircles(ETile orig) {
|
||||
this.orig = orig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return XDimension2D.delta(orig.calculateDimension(stringBounder), 2 * deltax, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final double linePos = linePos(ug.getStringBounder());
|
||||
final XDimension2D fullDim = calculateDimension(ug.getStringBounder());
|
||||
orig.drawU(ug.apply(UTranslate.dx(deltax)));
|
||||
ug = ug.apply(HColors.BLACK).apply(HColors.BLACK.bg());
|
||||
final UEllipse circle = new UEllipse(SIZE, SIZE);
|
||||
ug.apply(new UTranslate(0, linePos - SIZE / 2)).draw(circle);
|
||||
ug.apply(new UTranslate(fullDim.getWidth() - SIZE / 2, linePos - SIZE / 2)).draw(circle);
|
||||
ETileConcatenation.drawHline(ug, linePos, SIZE / 2, deltax);
|
||||
ETileConcatenation.drawHline(ug, linePos, fullDim.getWidth() - deltax, fullDim.getWidth() - SIZE / 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double linePos(StringBounder stringBounder) {
|
||||
return orig.linePos(stringBounder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(ETile tile) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
122
src/net/sourceforge/plantuml/ebnf/EbnfEngine.java
Normal file
122
src/net/sourceforge/plantuml/ebnf/EbnfEngine.java
Normal file
@ -0,0 +1,122 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.style.SName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
import net.sourceforge.plantuml.style.StyleSignatureBasic;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
|
||||
|
||||
public class EbnfEngine {
|
||||
|
||||
private final Deque<ETile> stack = new ArrayDeque<>();
|
||||
private final FontConfiguration fontConfiguration;
|
||||
private final Style style;
|
||||
private final HColorSet colorSet;
|
||||
|
||||
public EbnfEngine(ISkinParam skinParam) {
|
||||
this.style = getStyleSignature().getMergedStyle(skinParam.getCurrentStyleBuilder());
|
||||
this.fontConfiguration = style.getFontConfiguration(skinParam.getIHtmlColorSet());
|
||||
this.colorSet = skinParam.getIHtmlColorSet();
|
||||
|
||||
}
|
||||
|
||||
public void push(Token element) {
|
||||
stack.addFirst(new ETileBox(element.getData(), element.getSymbol(), fontConfiguration, style, colorSet));
|
||||
}
|
||||
|
||||
public void optional() {
|
||||
final ETile arg1 = stack.removeFirst();
|
||||
stack.addFirst(new ETileOptional(arg1));
|
||||
}
|
||||
|
||||
public void repetition() {
|
||||
final ETile arg1 = stack.removeFirst();
|
||||
stack.addFirst(new ETileRepetition(arg1));
|
||||
}
|
||||
|
||||
public void alternation() {
|
||||
final ETile arg1 = stack.removeFirst();
|
||||
final ETile arg2 = stack.removeFirst();
|
||||
if (arg1 instanceof ETileAlternation) {
|
||||
arg1.push(arg2);
|
||||
stack.addFirst(arg1);
|
||||
} else if (arg2 instanceof ETileAlternation) {
|
||||
arg2.push(arg1);
|
||||
stack.addFirst(arg2);
|
||||
} else {
|
||||
final ETile concat = new ETileAlternation();
|
||||
concat.push(arg1);
|
||||
concat.push(arg2);
|
||||
stack.addFirst(concat);
|
||||
}
|
||||
}
|
||||
|
||||
public void concatenation() {
|
||||
|
||||
final ETile arg1 = stack.removeFirst();
|
||||
final ETile arg2 = stack.removeFirst();
|
||||
if (arg1 instanceof ETileConcatenation) {
|
||||
arg1.push(arg2);
|
||||
stack.addFirst(arg1);
|
||||
} else if (arg2 instanceof ETileConcatenation) {
|
||||
arg2.push(arg1);
|
||||
stack.addFirst(arg2);
|
||||
} else {
|
||||
final ETile concat = new ETileConcatenation();
|
||||
concat.push(arg1);
|
||||
concat.push(arg2);
|
||||
stack.addFirst(concat);
|
||||
}
|
||||
}
|
||||
|
||||
public TextBlock getTextBlock() {
|
||||
if (stack.size() != 1)
|
||||
throw new IllegalStateException();
|
||||
return new ETileWithCircles(stack.peekFirst());
|
||||
}
|
||||
|
||||
private StyleSignatureBasic getStyleSignature() {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, SName.activityDiagram, SName.activity);
|
||||
}
|
||||
|
||||
}
|
54
src/net/sourceforge/plantuml/ebnf/EbnfExpressions.java
Normal file
54
src/net/sourceforge/plantuml/ebnf/EbnfExpressions.java
Normal file
@ -0,0 +1,54 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class EbnfExpressions {
|
||||
|
||||
public static List<EbnfSingleExpression> build(List<String> data) {
|
||||
final List<EbnfSingleExpression> all = new ArrayList<>();
|
||||
|
||||
final CharIterator it = new CharIteratorImpl(data);
|
||||
while (it.peek() != 0)
|
||||
all.add(new EbnfSingleExpression(it));
|
||||
|
||||
return Collections.unmodifiableList(all);
|
||||
}
|
||||
|
||||
}
|
@ -35,114 +35,105 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.style.SName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
import net.sourceforge.plantuml.style.StyleSignatureBasic;
|
||||
|
||||
interface CharIterator {
|
||||
char peek();
|
||||
|
||||
void next();
|
||||
}
|
||||
|
||||
class CharIteratorImpl implements CharIterator {
|
||||
|
||||
final private List<String> data;
|
||||
private int line = 0;
|
||||
private int pos = 0;
|
||||
|
||||
public CharIteratorImpl(List<String> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public char peek() {
|
||||
if (line == -1)
|
||||
return 0;
|
||||
return data.get(line).charAt(pos);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if (line == -1)
|
||||
throw new IllegalStateException();
|
||||
pos++;
|
||||
if (pos >= data.get(line).length()) {
|
||||
line++;
|
||||
pos = 0;
|
||||
}
|
||||
if (line >= data.size())
|
||||
line = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class EbnfExpression {
|
||||
public class EbnfSingleExpression {
|
||||
|
||||
final List<Token> tokens = new ArrayList<>();
|
||||
|
||||
public EbnfExpression(String... data) {
|
||||
this(Arrays.asList(data));
|
||||
}
|
||||
|
||||
public EbnfExpression(List<String> data) {
|
||||
final CharIterator it = new CharIteratorImpl(data);
|
||||
analyze(it);
|
||||
}
|
||||
|
||||
public UDrawable getUDrawable(ISkinParam skinParam) {
|
||||
final Iterator<Token> iterator = tokens.iterator();
|
||||
final Token name = iterator.next();
|
||||
final Token definition = iterator.next();
|
||||
final ShuntingYard shuntingYard = new ShuntingYard(iterator);
|
||||
|
||||
return build(shuntingYard.getOuputQueue(), skinParam);
|
||||
|
||||
}
|
||||
|
||||
private Alternation build(Iterator<Token> it, ISkinParam skinParam) {
|
||||
final Deque<Token> stack = new ArrayDeque<>();
|
||||
final Alternation ebnf = new Alternation(skinParam);
|
||||
while (it.hasNext()) {
|
||||
final Token element = it.next();
|
||||
if (element.getSymbol() == Symbol.TERMINAL_STRING1 || element.getSymbol() == Symbol.LITTERAL) {
|
||||
stack.addFirst(element);
|
||||
} else if (element.getSymbol() == Symbol.ALTERNATION) {
|
||||
ebnf.alternation(stack.removeFirst());
|
||||
} else {
|
||||
throw new UnsupportedOperationException(element.toString());
|
||||
}
|
||||
}
|
||||
ebnf.alternation(stack.removeFirst());
|
||||
|
||||
return ebnf;
|
||||
}
|
||||
|
||||
private void analyze(CharIterator it) {
|
||||
EbnfSingleExpression(CharIterator it) {
|
||||
while (true) {
|
||||
final char ch = it.peek();
|
||||
if (Character.isWhitespace(ch)) {
|
||||
} else if (isLetterOrDigit(ch)) {
|
||||
final String litteral = readLitteral(it);
|
||||
tokens.add(new Token(Symbol.LITTERAL, litteral));
|
||||
} else if (ch == ',') {
|
||||
tokens.add(new Token(Symbol.CONCATENATION, null));
|
||||
} else if (ch == '|') {
|
||||
tokens.add(new Token(Symbol.ALTERNATION, null));
|
||||
} else if (ch == '=') {
|
||||
tokens.add(new Token(Symbol.DEFINITION, null));
|
||||
} else if (ch == '(') {
|
||||
tokens.add(new Token(Symbol.GROUPING_OPEN, null));
|
||||
} else if (ch == ')') {
|
||||
tokens.add(new Token(Symbol.GROUPING_CLOSE, null));
|
||||
} else if (ch == '[') {
|
||||
tokens.add(new Token(Symbol.OPTIONAL_OPEN, null));
|
||||
} else if (ch == ']') {
|
||||
tokens.add(new Token(Symbol.OPTIONAL_CLOSE, null));
|
||||
} else if (ch == '{') {
|
||||
tokens.add(new Token(Symbol.REPETITION_OPEN, null));
|
||||
} else if (ch == '}') {
|
||||
tokens.add(new Token(Symbol.REPETITION_CLOSE, null));
|
||||
} else if (ch == ';' || ch == 0) {
|
||||
it.next();
|
||||
break;
|
||||
} else if (ch == '\"') {
|
||||
final String litteral = readString(it);
|
||||
tokens.add(new Token(Symbol.TERMINAL_STRING1, litteral));
|
||||
} else if (ch == '\'') {
|
||||
final String litteral = readString(it);
|
||||
tokens.add(new Token(Symbol.TERMINAL_STRING2, litteral));
|
||||
} else
|
||||
throw new UnsupportedOperationException("" + ch);
|
||||
it.next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
private StyleSignatureBasic getStyleSignature() {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, SName.activityDiagram, SName.activity);
|
||||
}
|
||||
|
||||
public TextBlock getUDrawable(ISkinParam skinParam) {
|
||||
final Iterator<Token> iterator = tokens.iterator();
|
||||
final Token name = iterator.next();
|
||||
final Token definition = iterator.next();
|
||||
final List<Token> full = new ShuntingYard(iterator).getOuputQueue();
|
||||
|
||||
final TextBlock main = getMainDrawing(skinParam, full.iterator());
|
||||
|
||||
final Style style = getStyleSignature().getMergedStyle(skinParam.getCurrentStyleBuilder());
|
||||
final FontConfiguration fc = style.getFontConfiguration(skinParam.getIHtmlColorSet());
|
||||
|
||||
final TitleBox titleBox = new TitleBox(name.getData() + ":", fc);
|
||||
|
||||
return TextBlockUtils.mergeTB(titleBox, TextBlockUtils.withMargin(main, 0, 0, 10, 15),
|
||||
HorizontalAlignment.LEFT);
|
||||
}
|
||||
|
||||
private TextBlock getMainDrawing(ISkinParam skinParam, Iterator<Token> it) {
|
||||
final EbnfEngine engine = new EbnfEngine(skinParam);
|
||||
while (it.hasNext()) {
|
||||
final Token element = it.next();
|
||||
if (element.getSymbol() == Symbol.TERMINAL_STRING1 || element.getSymbol() == Symbol.TERMINAL_STRING2
|
||||
|| element.getSymbol() == Symbol.LITTERAL)
|
||||
engine.push(element);
|
||||
else if (element.getSymbol() == Symbol.ALTERNATION)
|
||||
engine.alternation();
|
||||
else if (element.getSymbol() == Symbol.CONCATENATION)
|
||||
engine.concatenation();
|
||||
else if (element.getSymbol() == Symbol.OPTIONAL_CLOSE)
|
||||
engine.optional();
|
||||
else if (element.getSymbol() == Symbol.REPETITION_CLOSE)
|
||||
engine.repetition();
|
||||
else
|
||||
throw new UnsupportedOperationException(element.toString());
|
||||
}
|
||||
|
||||
return engine.getTextBlock();
|
||||
}
|
||||
|
||||
private String readString(CharIterator it) {
|
||||
@ -174,3 +165,40 @@ public class EbnfExpression {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface CharIterator {
|
||||
char peek();
|
||||
|
||||
void next();
|
||||
}
|
||||
|
||||
class CharIteratorImpl implements CharIterator {
|
||||
|
||||
final private List<String> data;
|
||||
private int line = 0;
|
||||
private int pos = 0;
|
||||
|
||||
public CharIteratorImpl(List<String> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public char peek() {
|
||||
if (line == -1)
|
||||
return 0;
|
||||
return data.get(line).charAt(pos);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if (line == -1)
|
||||
throw new IllegalStateException();
|
||||
pos++;
|
||||
if (pos >= data.get(line).length()) {
|
||||
line++;
|
||||
pos = 0;
|
||||
}
|
||||
while (line < data.size() && data.get(line).length() == 0)
|
||||
line++;
|
||||
if (line >= data.size())
|
||||
line = -1;
|
||||
}
|
||||
}
|
@ -46,7 +46,10 @@ import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.core.DiagramDescription;
|
||||
import net.sourceforge.plantuml.core.ImageData;
|
||||
import net.sourceforge.plantuml.core.UmlSource;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
|
||||
|
||||
public class PSystemEbnf extends TitledDiagram {
|
||||
|
||||
@ -70,8 +73,11 @@ public class PSystemEbnf extends TitledDiagram {
|
||||
return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
|
||||
}
|
||||
|
||||
private UDrawable getTextBlock() {
|
||||
final EbnfExpression exp = new EbnfExpression(lines);
|
||||
return exp.getUDrawable(getSkinParam());
|
||||
private TextBlockBackcolored getTextBlock() {
|
||||
final List<EbnfSingleExpression> all = EbnfExpressions.build(lines);
|
||||
TextBlock result = all.get(0).getUDrawable(getSkinParam());
|
||||
for (int i = 1; i < all.size(); i++)
|
||||
result = TextBlockUtils.mergeTB(result, all.get(i).getUDrawable(getSkinParam()), HorizontalAlignment.LEFT);
|
||||
return TextBlockUtils.addBackcolor(result, null);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -49,9 +50,35 @@ public class ShuntingYard {
|
||||
public ShuntingYard(Iterator<Token> it) {
|
||||
while (it.hasNext()) {
|
||||
final Token token = it.next();
|
||||
if (token.getSymbol() == Symbol.LITTERAL || token.getSymbol() == Symbol.TERMINAL_STRING1) {
|
||||
if (token.getSymbol() == Symbol.LITTERAL || token.getSymbol() == Symbol.TERMINAL_STRING1
|
||||
|| token.getSymbol() == Symbol.TERMINAL_STRING2) {
|
||||
ouputQueue.add(token);
|
||||
} else if (token.getSymbol() == Symbol.ALTERNATION) {
|
||||
} else if (token.getSymbol().isOperator()) {
|
||||
while (thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(token))
|
||||
ouputQueue.add(operatorStack.removeFirst());
|
||||
operatorStack.addFirst(token);
|
||||
} else if (token.getSymbol() == Symbol.GROUPING_OPEN) {
|
||||
operatorStack.addFirst(token);
|
||||
} else if (token.getSymbol() == Symbol.GROUPING_CLOSE) {
|
||||
while (operatorStack.peekFirst().getSymbol() != Symbol.GROUPING_OPEN)
|
||||
ouputQueue.add(operatorStack.removeFirst());
|
||||
if (operatorStack.peekFirst().getSymbol() == Symbol.GROUPING_OPEN)
|
||||
operatorStack.removeFirst();
|
||||
} else if (token.getSymbol() == Symbol.OPTIONAL_OPEN) {
|
||||
operatorStack.addFirst(token);
|
||||
} else if (token.getSymbol() == Symbol.OPTIONAL_CLOSE) {
|
||||
while (operatorStack.peekFirst().getSymbol() != Symbol.OPTIONAL_OPEN)
|
||||
ouputQueue.add(operatorStack.removeFirst());
|
||||
if (operatorStack.peekFirst().getSymbol() == Symbol.OPTIONAL_OPEN)
|
||||
operatorStack.removeFirst();
|
||||
operatorStack.addFirst(token);
|
||||
} else if (token.getSymbol() == Symbol.REPETITION_OPEN) {
|
||||
operatorStack.addFirst(token);
|
||||
} else if (token.getSymbol() == Symbol.REPETITION_CLOSE) {
|
||||
while (operatorStack.peekFirst().getSymbol() != Symbol.REPETITION_OPEN)
|
||||
ouputQueue.add(operatorStack.removeFirst());
|
||||
if (operatorStack.peekFirst().getSymbol() == Symbol.REPETITION_OPEN)
|
||||
operatorStack.removeFirst();
|
||||
operatorStack.addFirst(token);
|
||||
} else {
|
||||
throw new UnsupportedOperationException(token.toString());
|
||||
@ -64,8 +91,16 @@ public class ShuntingYard {
|
||||
}
|
||||
}
|
||||
|
||||
public final Iterator<Token> getOuputQueue() {
|
||||
return ouputQueue.iterator();
|
||||
private boolean thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(Token token) {
|
||||
final Token top = operatorStack.peekFirst();
|
||||
if (top != null && top.getSymbol().isOperator()
|
||||
&& top.getSymbol().getPriority() > token.getSymbol().getPriority())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public final List<Token> getOuputQueue() {
|
||||
return Collections.unmodifiableList(ouputQueue);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,19 +38,36 @@ package net.sourceforge.plantuml.ebnf;
|
||||
public enum Symbol {
|
||||
|
||||
LITTERAL, //
|
||||
|
||||
|
||||
// https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form
|
||||
DEFINITION, // =
|
||||
CONCATENATION, // ,
|
||||
TERMINATION, // ;
|
||||
ALTERNATION, // |
|
||||
OPTIONAL, // [ ]
|
||||
REPETITION, // { }
|
||||
GROUPING, // ( )
|
||||
OPTIONAL_OPEN, // [
|
||||
OPTIONAL_CLOSE, // ]
|
||||
REPETITION_OPEN, // {
|
||||
REPETITION_CLOSE, // }
|
||||
GROUPING_OPEN, // (
|
||||
GROUPING_CLOSE, // )
|
||||
TERMINAL_STRING1, // " "
|
||||
TERMINAL_STRING2, // ' '
|
||||
COMMENT, // (* *)
|
||||
SPECIAL_SEQUENCE, // ? ?
|
||||
EXCEPTION; // -
|
||||
|
||||
public int getPriority() {
|
||||
switch (this) {
|
||||
case CONCATENATION:
|
||||
return 2;
|
||||
case ALTERNATION:
|
||||
return 1;
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
boolean isOperator() {
|
||||
return this == CONCATENATION || this == ALTERNATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
71
src/net/sourceforge/plantuml/ebnf/TitleBox.java
Normal file
71
src/net/sourceforge/plantuml/ebnf/TitleBox.java
Normal file
@ -0,0 +1,71 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.FontStyle;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UText;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public class TitleBox extends AbstractTextBlock {
|
||||
|
||||
private final String value;
|
||||
private final FontConfiguration fc;
|
||||
private final UText utext;
|
||||
|
||||
public TitleBox(String value, FontConfiguration fc) {
|
||||
this.value = value;
|
||||
this.fc = fc.add(FontStyle.BOLD);
|
||||
this.utext = new UText(value, this.fc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return stringBounder.calculateDimension(fc.getFont(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
final XDimension2D dimText = calculateDimension(ug.getStringBounder());
|
||||
|
||||
ug.apply(new UTranslate(0, dimText.getHeight() - utext.getDescent(ug.getStringBounder()))).draw(utext);
|
||||
}
|
||||
|
||||
}
|
@ -37,38 +37,27 @@ package net.sourceforge.plantuml.ebnf;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public class HLineCurved implements UDrawable {
|
||||
public class VLineCurved implements UDrawable {
|
||||
|
||||
private final double height;
|
||||
private final double delta;
|
||||
private final UDrawable top;
|
||||
private final UDrawable bottom;
|
||||
|
||||
public HLineCurved(double height, double delta) {
|
||||
public VLineCurved(double height, double delta, UDrawable top, UDrawable bottom) {
|
||||
this.height = height;
|
||||
this.delta = delta;
|
||||
this.bottom = bottom;
|
||||
this.top = top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawU(UGraphic ug) {
|
||||
if (delta == 0) {
|
||||
ug.draw(ULine.vline(height));
|
||||
return;
|
||||
}
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(-delta, 0);
|
||||
|
||||
final double a = delta / 4;
|
||||
path.cubicTo(-a, 0, 0, Math.abs(a), 0, Math.abs(delta));
|
||||
// path.lineTo(0, delta);
|
||||
|
||||
path.lineTo(0, height - Math.abs(delta));
|
||||
|
||||
path.cubicTo(0, height - a, a, height, delta, height);
|
||||
// path.lineTo(delta, height);
|
||||
|
||||
ug.draw(path);
|
||||
bottom.drawU(ug.apply(UTranslate.dy(height)));
|
||||
ETileConcatenation.drawVline(ug, 0, delta, height - delta);
|
||||
top.drawU(ug);
|
||||
}
|
||||
|
||||
}
|
@ -450,7 +450,8 @@ public class ImageBuilder {
|
||||
if (this.backcolor instanceof HColorSimple)
|
||||
pngBackColor = this.backcolor.toColor(fileFormatOption.getColorMapper());
|
||||
|
||||
if (OptionFlags.getInstance().isReplaceWhiteBackgroundByTransparent() && Color.WHITE.equals(pngBackColor))
|
||||
if (OptionFlags.getInstance().isReplaceWhiteBackgroundByTransparent()
|
||||
&& (Color.WHITE.equals(pngBackColor) || Color.BLACK.equals(pngBackColor)))
|
||||
pngBackColor = new Color(0, 0, 0, 0);
|
||||
|
||||
final EmptyImageBuilder builder = new EmptyImageBuilder(watermark, (int) (dim.getWidth() * scaleFactor),
|
||||
|
@ -45,7 +45,7 @@ public class Version {
|
||||
private static final int MAJOR_SEPARATOR = 1000000;
|
||||
|
||||
public static int version() {
|
||||
return 1202208;
|
||||
return 1202209;
|
||||
}
|
||||
|
||||
public static int versionPatched() {
|
||||
@ -94,7 +94,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static long compileTime() {
|
||||
return 1664096433281L;
|
||||
return 1664295006047L;
|
||||
}
|
||||
|
||||
public static String compileTimeString() {
|
||||
|
Loading…
Reference in New Issue
Block a user