diff --git a/src/net/sourceforge/plantuml/EmbeddedDiagram.java b/src/net/sourceforge/plantuml/EmbeddedDiagram.java index db3f0fe7b..d7954764d 100644 --- a/src/net/sourceforge/plantuml/EmbeddedDiagram.java +++ b/src/net/sourceforge/plantuml/EmbeddedDiagram.java @@ -45,6 +45,7 @@ import java.util.List; import net.sourceforge.plantuml.awt.geom.XDimension2D; import net.sourceforge.plantuml.core.Diagram; +import net.sourceforge.plantuml.creole.Neutron; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -146,10 +147,6 @@ public class EmbeddedDiagram extends AbstractTextBlock implements Line, Atom { return new EmbeddedDiagram(skinParam, BlockUml.convert(strings)); } - public List splitInTwo(StringBounder stringBounder, double width) { - return Arrays.asList((Atom) this); - } - public double getStartingAltitude(StringBounder stringBounder) { return 0; } @@ -219,4 +216,9 @@ public class EmbeddedDiagram extends AbstractTextBlock implements Line, Atom { } + @Override + public List getNeutrons() { + return Arrays.asList(Neutron.create(this)); + } + } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/creole/Fission.java b/src/net/sourceforge/plantuml/creole/Fission.java index 1c8874a8c..048b29f9d 100644 --- a/src/net/sourceforge/plantuml/creole/Fission.java +++ b/src/net/sourceforge/plantuml/creole/Fission.java @@ -35,9 +35,11 @@ */ package net.sourceforge.plantuml.creole; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Deque; import java.util.List; import java.util.Objects; @@ -59,41 +61,43 @@ public class Fission { } public List getSplitted(StringBounder stringBounder) { - final double valueMaxWidth = maxWidth.getMaxWidth(); + final double valueMaxWidth = Math.abs(maxWidth.getMaxWidth()); if (valueMaxWidth == 0) return Arrays.asList(stripe); final List result = new ArrayList<>(); - StripeSimpleInternal current = new StripeSimpleInternal(stripe.getLHeader()); - double remainingSpace = valueMaxWidth; - for (Atom atom : noHeader()) - while (true) { - final List splitInTwo = atom.splitInTwo(stringBounder, remainingSpace); - final Atom part1 = splitInTwo.get(0); - final double widthPart1 = part1.calculateDimension(stringBounder).getWidth(); - current.addAtom(part1); - remainingSpace -= widthPart1; - if (remainingSpace <= 0) { - result.add(current); - current = new StripeSimpleInternal(blank(stripe.getLHeader())); - remainingSpace = valueMaxWidth; - } - if (splitInTwo.size() == 1) { - break; - } - atom = splitInTwo.get(1); - if (remainingSpace < valueMaxWidth - && atom.calculateDimension(stringBounder).getWidth() > remainingSpace) { - result.add(current); - current = new StripeSimpleInternal(blank(stripe.getLHeader())); - remainingSpace = valueMaxWidth; - } - } + StripeSimpleInternal line = new StripeSimpleInternal(false, stringBounder, stripe.getLHeader()); + result.add(line); - if (remainingSpace < valueMaxWidth) - result.add(current); + final Deque all = new ArrayDeque<>(); + for (Atom atom : noHeader()) + for (Neutron n : atom.getNeutrons()) + all.addLast(n); + if (all.peekLast().getType() != NeutronType.ZWSP_SEPARATOR) + all.addLast(Neutron.zwspSeparator()); + + while (all.size() > 0) { + final Neutron current = all.removeFirst(); + if (current.getType() == NeutronType.ZWSP_SEPARATOR && line.getWidth() > valueMaxWidth) { + all.addFirst(current); + final List removed = line.slightyShorten(); + for (int i = removed.size() - 1; i >= 0; i--) + all.addFirst(removed.get(i)); + + line = new StripeSimpleInternal(true, stringBounder, blank(stripe.getLHeader())); + result.add(line); + } else + line.addNeutron(current); + } + + for (Stripe l : result) + ((StripeSimpleInternal) l).removeFinalSpaces(); + + while (result.size() > 1 && ((StripeSimpleInternal) result.get(result.size() - 1)).isWhite()) + result.remove(result.size() - 1); return Collections.unmodifiableList(result); + } private List noHeader() { @@ -104,6 +108,121 @@ public class Fission { return atoms.subList(1, atoms.size()); } + static class StripeSimpleInternal implements Stripe { + + private final boolean removeInitialSpaces; + private final Atom header; + private final List neutrons = new ArrayList<>(); + private final StringBounder stringBounder; + private double width; + + private StripeSimpleInternal(boolean removeInitialSpaces, StringBounder stringBounder, Atom header) { + this.removeInitialSpaces = removeInitialSpaces; + this.stringBounder = stringBounder; + this.header = header; + if (header != null) + width += header.calculateDimension(stringBounder).getWidth(); + } + + public double getWidth() { + if (width == -1) + throw new IllegalStateException(); +// double width = 0; +// if (header != null) +// width += header.calculateDimension(stringBounder).getWidth(); +// for (Neutron n : neutrons) +// width += n.getWidth(stringBounder); + return width; + } + + @Override + public String toString() { + if (header != null) + return header.toString() + " " + neutrons; + return neutrons.toString(); + } + + public List slightyShorten() { + if (neutrons.size() == 0) + throw new IllegalStateException(); + + final int lastZwsp = lastZwsp(); + if (lastZwsp == -1) + return Collections.emptyList(); + + this.width = -1; + final List removed = new ArrayList(neutrons.subList(lastZwsp, neutrons.size())); + while (neutrons.size() > lastZwsp) + neutrons.remove(neutrons.size() - 1); + + return removed; + + } + + private boolean isWhite() { + for (Neutron n : neutrons) + if (n.getType() != NeutronType.ZWSP_SEPARATOR && n.getType() != NeutronType.SPACE) + return false; + return true; + } + + private void removeFinalSpaces() { + while (neutrons.size() > 0 && neutrons.get(0).getType() == NeutronType.ZWSP_SEPARATOR) + neutrons.remove(0); + while (neutrons.size() > 1 + && (last().getType() == NeutronType.SPACE || last().getType() == NeutronType.ZWSP_SEPARATOR)) + neutrons.remove(neutrons.size() - 1); + } + + private Neutron last() { + return neutrons.get(neutrons.size() - 1); + } + + private int lastZwsp() { + for (int i = neutrons.size() - 1; i >= 0; i--) + if (neutrons.get(i).getType() == NeutronType.ZWSP_SEPARATOR) + return i; + return -1; + } + + public List getAtoms() { + final List result = new ArrayList<>(); + if (header != null) + result.add(header); + + for (Neutron n : neutrons) + if (n.getType() != NeutronType.ZWSP_SEPARATOR) { + if (removeInitialSpaces && result.size() == 0 && n.getType() == NeutronType.SPACE) + continue; + result.add(n.asAtom()); + } + return Collections.unmodifiableList(result); + } + + private void addNeutron(Neutron neutron) { + if (width == -1) + throw new IllegalStateException(); + + if (neutron.getType() == NeutronType.ZWSP_SEPARATOR && this.neutrons.size() == 0) + return; + + if (neutron.getType() == NeutronType.ZWSP_SEPARATOR && this.neutrons.size() > 0 + && last().getType() == NeutronType.ZWSP_SEPARATOR) + return; + + if (removeInitialSpaces && this.neutrons.size() == 0 && neutron.getType() == NeutronType.SPACE) + return; + + this.neutrons.add(neutron); + this.width += neutron.getWidth(stringBounder); + } + + public Atom getLHeader() { + return null; + } + + } + private static Atom blank(final Atom header) { if (header == null) return null; @@ -124,28 +243,4 @@ public class Fission { }; } - static class StripeSimpleInternal implements Stripe { - - private final List atoms = new ArrayList<>(); - - private StripeSimpleInternal(Atom header) { - if (header != null) - this.atoms.add(header); - - } - - public List getAtoms() { - return Collections.unmodifiableList(atoms); - } - - private void addAtom(Atom atom) { - this.atoms.add(atom); - } - - public Atom getLHeader() { - return null; - } - - } - } diff --git a/src/net/sourceforge/plantuml/creole/Neutron.java b/src/net/sourceforge/plantuml/creole/Neutron.java new file mode 100644 index 000000000..35e6a74da --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/Neutron.java @@ -0,0 +1,114 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole; + +import net.sourceforge.plantuml.creole.atom.Atom; +import net.sourceforge.plantuml.creole.legacy.AtomText; +import net.sourceforge.plantuml.graphic.StringBounder; + +public class Neutron { + + private final String data; + private final NeutronType type; + private final Atom asAtom; + + private Neutron(String data, NeutronType type, Atom asAtom) { + this.data = data; + this.type = type; + this.asAtom = asAtom; + } + + public static Neutron create(Atom atom) { + if (atom instanceof AtomText) { + final String text = ((AtomText) atom).getText(); + return new Neutron(text, getNeutronTypeFromChar(text.charAt(0)), atom); + } + return new Neutron(null, NeutronType.OTHER, atom); + } + + public static Neutron zwspSeparator() { + return new Neutron(null, NeutronType.ZWSP_SEPARATOR, null); + } + + @Override + public String toString() { + if (type == NeutronType.ZWSP_SEPARATOR) + return "ZWSP"; + return type + "(" + data + ")"; + } + + public Atom asAtom() { + return asAtom; + } + + public NeutronType getType() { + return type; + } + + public static boolean isSeparator(char ch) { + return Character.isWhitespace(ch); + } + + private static boolean isSentenceBoundaryUnused(char ch) { + return ch == '.' || ch == ','; + + } + + public static boolean isChineseSentenceBoundary(char ch) { + return ch == '\uFF01' // U+FF01 FULLWIDTH EXCLAMATION MARK (!) +// || ch == '\uFF08' // U+FF08 FULLWIDTH LEFT PARENTHESIS +// || ch == '\uFF09' // U+FF09 FULLWIDTH RIGHT PARENTHESIS + || ch == '\uFF0C' // U+FF0C FULLWIDTH COMMA + || ch == '\uFF1A' // U+FF1A FULLWIDTH COLON (:) + || ch == '\uFF1B' // U+FF1B FULLWIDTH SEMICOLON (;) + || ch == '\uFF1F' // U+FF1F FULLWIDTH QUESTION MARK (?) + || ch == '\u3002'; // U+3002 IDEOGRAPHIC FULL STOP (.) + } + + public double getWidth(StringBounder stringBounder) { + if (type == NeutronType.ZWSP_SEPARATOR) + return 0; + + return asAtom.calculateDimension(stringBounder).getWidth(); + } + + public static NeutronType getNeutronTypeFromChar(char ch) { + if (isSeparator(ch)) + return NeutronType.SPACE; + return NeutronType.TEXT; + } + +} diff --git a/src/net/sourceforge/plantuml/creole/NeutronType.java b/src/net/sourceforge/plantuml/creole/NeutronType.java new file mode 100644 index 000000000..260c68c42 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/NeutronType.java @@ -0,0 +1,41 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2023, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.creole; + +public enum NeutronType { + TEXT, SPACE, ZWSP_SEPARATOR, OTHER; + +} diff --git a/src/net/sourceforge/plantuml/creole/Parser.java b/src/net/sourceforge/plantuml/creole/Parser.java index 3ecb29ea3..da151b8bb 100644 --- a/src/net/sourceforge/plantuml/creole/Parser.java +++ b/src/net/sourceforge/plantuml/creole/Parser.java @@ -38,11 +38,6 @@ package net.sourceforge.plantuml.creole; import java.util.regex.Matcher; import java.util.regex.Pattern; -import net.sourceforge.plantuml.ISkinSimple; -import net.sourceforge.plantuml.creole.legacy.CreoleParser; -import net.sourceforge.plantuml.graphic.FontConfiguration; -import net.sourceforge.plantuml.graphic.HorizontalAlignment; - public class Parser { public static final String MONOSPACED = "monospaced"; diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock1.java b/src/net/sourceforge/plantuml/creole/SheetBlock1.java index ea76b5dc8..a566b398c 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock1.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock1.java @@ -61,10 +61,6 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, Stencil { - public List splitInTwo(StringBounder stringBounder, double width) { - throw new UnsupportedOperationException(getClass().toString()); - } - private final Sheet sheet; private List stripes; private Map heights; @@ -222,4 +218,9 @@ public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, S return minimumWidth; } + @Override + public List getNeutrons() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/creole/SheetBlock2.java b/src/net/sourceforge/plantuml/creole/SheetBlock2.java index c16c83c5f..c5acf2193 100644 --- a/src/net/sourceforge/plantuml/creole/SheetBlock2.java +++ b/src/net/sourceforge/plantuml/creole/SheetBlock2.java @@ -55,10 +55,6 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; final public class SheetBlock2 extends AbstractTextBlock implements TextBlock, Atom, WithPorts { - public List splitInTwo(StringBounder stringBounder, double width) { - throw new UnsupportedOperationException(getClass().toString()); - } - private final SheetBlock1 block; private final UStroke defaultStroke; private final Stencil stencil; @@ -122,4 +118,9 @@ final public class SheetBlock2 extends AbstractTextBlock implements TextBlock, A return new Ports(); } + @Override + public List getNeutrons() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/creole/atom/AbstractAtom.java b/src/net/sourceforge/plantuml/creole/atom/AbstractAtom.java index 10d77b932..c3efda3f6 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AbstractAtom.java +++ b/src/net/sourceforge/plantuml/creole/atom/AbstractAtom.java @@ -38,12 +38,12 @@ package net.sourceforge.plantuml.creole.atom; import java.util.Arrays; import java.util.List; -import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.creole.Neutron; public abstract class AbstractAtom implements Atom { - public List splitInTwo(StringBounder stringBounder, double width) { - return Arrays.asList((Atom) this); + public List getNeutrons() { + return Arrays.asList(Neutron.create(this)); } } diff --git a/src/net/sourceforge/plantuml/creole/atom/Atom.java b/src/net/sourceforge/plantuml/creole/atom/Atom.java index d4e16702f..0524ebcb0 100644 --- a/src/net/sourceforge/plantuml/creole/atom/Atom.java +++ b/src/net/sourceforge/plantuml/creole/atom/Atom.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.creole.atom; import java.util.List; import net.sourceforge.plantuml.awt.geom.XDimension2D; +import net.sourceforge.plantuml.creole.Neutron; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UShape; @@ -50,6 +51,6 @@ public interface Atom extends UShape { public void drawU(UGraphic ug); - public List splitInTwo(StringBounder stringBounder, double width); + public List getNeutrons(); } diff --git a/src/net/sourceforge/plantuml/creole/atom/AtomWithMargin.java b/src/net/sourceforge/plantuml/creole/atom/AtomWithMargin.java index 6510e04e4..1ac67ce1e 100644 --- a/src/net/sourceforge/plantuml/creole/atom/AtomWithMargin.java +++ b/src/net/sourceforge/plantuml/creole/atom/AtomWithMargin.java @@ -35,10 +35,6 @@ */ package net.sourceforge.plantuml.creole.atom; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import net.sourceforge.plantuml.awt.geom.XDimension2D; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -56,24 +52,6 @@ public class AtomWithMargin extends AbstractAtom implements Atom { this.marginY2 = marginY2; } - @Override - public List splitInTwo(StringBounder stringBounder, double width) { - final List result = new ArrayList<>(); - final List list = atom.splitInTwo(stringBounder, width); - for (Atom a : list) { - double y1 = marginY1; - double y2 = marginY2; - if (list.size() == 2 && result.size() == 0) { - y2 = 0; - } - if (list.size() == 2 && result.size() == 1) { - y1 = 0; - } - result.add(new AtomWithMargin(a, y1, y2)); - } - return Collections.unmodifiableList(result); - } - public XDimension2D calculateDimension(StringBounder stringBounder) { return atom.calculateDimension(stringBounder).delta(0, marginY1 + marginY2); } diff --git a/src/net/sourceforge/plantuml/creole/legacy/AtomText.java b/src/net/sourceforge/plantuml/creole/legacy/AtomText.java index 355827705..77220f706 100644 --- a/src/net/sourceforge/plantuml/creole/legacy/AtomText.java +++ b/src/net/sourceforge/plantuml/creole/legacy/AtomText.java @@ -36,23 +36,20 @@ package net.sourceforge.plantuml.creole.legacy; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.StringTokenizer; import net.sourceforge.plantuml.BackSlash; -import net.sourceforge.plantuml.LineBreakStrategy; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.awt.geom.XDimension2D; +import net.sourceforge.plantuml.creole.Neutron; +import net.sourceforge.plantuml.creole.NeutronType; import net.sourceforge.plantuml.creole.atom.AbstractAtom; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UText; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -71,23 +68,12 @@ public final class AtomText extends AbstractAtom implements Atom { private final DelayedDouble marginRight; private final Url url; private final boolean manageSpecialChars; - private TextBlock visibility; protected AtomText(String text, FontConfiguration style, Url url, DelayedDouble marginLeft, DelayedDouble marginRight, boolean manageSpecialChars) { if (text.contains("" + BackSlash.hiddenNewLine())) throw new IllegalArgumentException(text); -// if (text.length() > 0) { -// final VisibilityModifier visibilityModifier = VisibilityModifier.getByUnicode(text.charAt(0)); -// if (visibilityModifier != null) { -// final HColor back = HColorUtils.GREEN; -// final HColor fore = HColorUtils.RED; -// visibility = visibilityModifier.getUBlock(11, fore, back, url != null); -// text = text.substring(1); -// } -// } - this.marginLeft = marginLeft; this.marginRight = marginRight; String s = CharHidder.unhide(text); @@ -119,9 +105,6 @@ public final class AtomText extends AbstractAtom implements Atom { double width = text.indexOf("\t") == -1 ? rect.getWidth() : getWidth(stringBounder, text); final double left = marginLeft.getDouble(stringBounder); final double right = marginRight.getDouble(stringBounder); - if (visibility != null) - width += visibility.calculateDimension(stringBounder).getWidth(); - return new XDimension2D(width + left + right, h); } @@ -132,11 +115,6 @@ public final class AtomText extends AbstractAtom implements Atom { if (ug.matchesProperty("SPECIALTXT")) { ug.draw(this); } else { - if (visibility != null) { - visibility.drawU(ug.apply(UTranslate.dy(2))); - final double width = visibility.calculateDimension(ug.getStringBounder()).getWidth(); - ug = ug.apply(UTranslate.dx(width)); - } HColor textColor = fontConfiguration.getColor(); FontConfiguration useFontConfiguration = fontConfiguration; @@ -213,106 +191,44 @@ public final class AtomText extends AbstractAtom implements Atom { return stringBounder.calculateDimension(fontConfiguration.getFont(), tabString()).getWidth(); } - private final Collection splitted() { - final List result = new ArrayList<>(); + @Override + public final List getNeutrons() { + final List result = new ArrayList<>(); final StringBuilder pending = new StringBuilder(); for (int i = 0; i < text.length(); i++) { final char ch = text.charAt(i); - if (isSeparator(ch)) { - if (pending.length() > 0) - result.add(pending.toString()); - result.add("" + ch); - pending.setLength(0); - } else if (isChineseSentenceBoundary(ch)) { - pending.append(ch); - result.add(pending.toString()); - pending.setLength(0); - } else { + if (pending.length() == 0) { pending.append(ch); + continue; + } + final NeutronType pendingType = Neutron.getNeutronTypeFromChar(pending.charAt(0)); + final NeutronType currentType = Neutron.getNeutronTypeFromChar(ch); + if (pendingType != currentType) { + addPending(result, pending.toString()); + pending.setLength(0); + } + pending.append(ch); + // if (Neutron.isSentenceBoundary(ch) || Neutron.isChineseSentenceBoundary(ch)) + if (Neutron.isChineseSentenceBoundary(ch)) { + addPending(result, pending.toString()); + pending.setLength(0); + result.add(Neutron.zwspSeparator()); } - } - if (pending.length() > 0) - result.add(pending.toString()); - return result; - } - private final Collection splittedOld() { - final List result = new ArrayList<>(); - for (int i = 0; i < text.length(); i++) { - final char ch = text.charAt(i); - if (isSeparator(ch)) { - result.add("" + text.charAt(i)); - } else { - final StringBuilder tmp = new StringBuilder(); - tmp.append(ch); - while (i + 1 < text.length() && isSeparator(text.charAt(i + 1)) == false) { - i++; - tmp.append(text.charAt(i)); - } - result.add(tmp.toString()); - } + } + if (pending.length() > 0) { + addPending(result, pending.toString()); } return result; } - public List getSplitted(StringBounder stringBounder, LineBreakStrategy maxWidthAsString) { - final double maxWidth = maxWidthAsString.getMaxWidth(); - if (maxWidth == 0) - throw new IllegalStateException(); - - final List result = new ArrayList<>(); - final StringTokenizer st = new StringTokenizer(text, " ", true); - final StringBuilder currentLine = new StringBuilder(); - while (st.hasMoreTokens()) { - final String token1 = st.nextToken(); - for (String tmp : Arrays.asList(token1)) { - final double w = getWidth(stringBounder, currentLine + tmp); - if (w > maxWidth) { - result.add(withText(currentLine.toString())); - currentLine.setLength(0); - if (tmp.startsWith(" ") == false) - currentLine.append(tmp); - - } else { - currentLine.append(tmp); - } - } - } - result.add(withText(currentLine.toString())); - return Collections.unmodifiableList(result); - } - - @Override - public List splitInTwo(StringBounder stringBounder, double width) { - final StringBuilder tmp = new StringBuilder(); - for (String token : splitted()) { - if (tmp.length() > 0 && getWidth(stringBounder, tmp.toString() + token) > width) { - final Atom part1 = withText(tmp.toString()); - String remain = text.substring(tmp.length()); - while (remain.startsWith(" ")) - remain = remain.substring(1); - - final Atom part2 = withText(remain); - return Arrays.asList(part1, part2); - } - tmp.append(token); - } - return Collections.singletonList((Atom) this); - } - - private boolean isSeparator(char ch) { - return Character.isWhitespace(ch); - } - - private boolean isChineseSentenceBoundary(char ch) { - return ch == '\uFF01' // U+FF01 FULLWIDTH EXCLAMATION MARK (!) -// || ch == '\uFF08' // U+FF08 FULLWIDTH LEFT PARENTHESIS -// || ch == '\uFF09' // U+FF09 FULLWIDTH RIGHT PARENTHESIS - || ch == '\uFF0C' // U+FF0C FULLWIDTH COMMA - || ch == '\uFF1A' // U+FF1A FULLWIDTH COLON (:) - || ch == '\uFF1B' // U+FF1B FULLWIDTH SEMICOLON (;) - || ch == '\uFF1F' // U+FF1F FULLWIDTH QUESTION MARK (?) - || ch == '\u3002'; // U+3002 IDEOGRAPHIC FULL STOP (.) + private void addPending(List result, String pending) { + final Neutron tmp = Neutron.create(withText(pending)); + if (tmp.getType() == NeutronType.SPACE) + result.add(Neutron.zwspSeparator()); + result.add(tmp); + if (tmp.getType() == NeutronType.SPACE) + result.add(Neutron.zwspSeparator()); } public final String getText() { diff --git a/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java b/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java index 2521822d2..1ac6d4a22 100644 --- a/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeCode.java @@ -36,11 +36,11 @@ package net.sourceforge.plantuml.creole.legacy; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.awt.geom.XDimension2D; +import net.sourceforge.plantuml.creole.Neutron; import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.graphic.FontConfiguration; @@ -109,8 +109,9 @@ public class StripeCode implements StripeRaw { } } - public List splitInTwo(StringBounder stringBounder, double width) { - return Arrays.asList((Atom) this); + @Override + public List getNeutrons() { + throw new UnsupportedOperationException(); } } diff --git a/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java b/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java index fbaf50549..c322b9078 100644 --- a/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java +++ b/src/net/sourceforge/plantuml/creole/legacy/StripeLatex.java @@ -35,11 +35,11 @@ */ package net.sourceforge.plantuml.creole.legacy; -import java.util.Arrays; import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.awt.geom.XDimension2D; +import net.sourceforge.plantuml.creole.Neutron; import net.sourceforge.plantuml.creole.Parser; import net.sourceforge.plantuml.creole.atom.Atom; import net.sourceforge.plantuml.creole.atom.AtomMath; @@ -103,8 +103,9 @@ public class StripeLatex implements StripeRaw { getAtom().drawU(ug); } - public List splitInTwo(StringBounder stringBounder, double width) { - return Arrays.asList((Atom) this); + @Override + public List getNeutrons() { + throw new UnsupportedOperationException(); } } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index b055be947..5b7d13921 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -81,7 +81,7 @@ public class Version { } public static int beta() { - final int beta = 0; + final int beta = 1; return beta; }