1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-06-04 09:30:48 +00:00

version 8051

This commit is contained in:
Arnaud Roques 2016-12-01 21:29:25 +01:00
parent c2f885ffb5
commit 23f63f7ae2
153 changed files with 5225 additions and 759 deletions

View File

@ -65,7 +65,7 @@
<manifest>
<attribute name="Main-Class" value="net.sourceforge.plantuml.Run" />
<attribute name="SplashScreen-Image" value="net/sourceforge/plantuml/version/logo.png" />
<attribute name="Class-Path" value="batik-all-1.7.jar commons-io-1.3.1.jar commons-logging-1.1.1.jar jeuclid-core-3.1.9.jar xmlgraphics-commons-1.3.1.jar fop.jar vizjs.jar j2v8_win32_x86_64-3.1.6.jar j2v8_linux_x86_64-3.1.6.jar j2v8_macosx_x86_64-3.1.6.jar" />
<attribute name="Class-Path" value="batik-all-1.7.jar jlatexmath-minimal-1.0.3.jar jlm_cyrillic.jar jlm_greek.jar vizjs.jar j2v8_win32_x86_64-3.1.6.jar j2v8_linux_x86_64-3.1.6.jar j2v8_macosx_x86_64-3.1.6.jar" />
</manifest>
</jar>
<delete dir="build" />

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>8051-SNAPSHOT</version>
<version>8052-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>
@ -117,6 +117,7 @@
<include>net/sourceforge/plantuml/fun/*.png</include>
<include>sprites/archimate/*.png</include>
<include>net/sourceforge/plantuml/dedication/*.png</include>
<include>net/sourceforge/plantuml/math/*.js</include>
</includes>
</resource>
</resources>

View File

@ -30,16 +30,21 @@
*/
package net.sourceforge.plantuml;
import java.io.IOException;
import java.io.OutputStream;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.Command;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.ProtectedCommand;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.core.UmlSource;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.VerticalAlignment;
import net.sourceforge.plantuml.stats.StatsUtilsIncrement;
import net.sourceforge.plantuml.version.License;
import net.sourceforge.plantuml.version.Version;
@ -110,4 +115,17 @@ public abstract class AbstractPSystem implements Diagram {
return false;
}
final public ImageData exportDiagram(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
final long now = System.currentTimeMillis();
try {
return exportDiagramNow(os, index, fileFormatOption);
} finally {
StatsUtilsIncrement.onceMoreGenerate(System.currentTimeMillis() - now, getClass(), fileFormatOption.getFileFormat());
}
}
protected abstract ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException;
}

View File

@ -79,7 +79,7 @@ public interface ISkinParam extends ISkinSimple {
public String getDotExecutable();
public boolean shadowing();
public boolean shadowingForNote(Stereotype stereotype);
public boolean shadowing2(SkinParameter skinParameter);
@ -121,14 +121,15 @@ public interface ISkinParam extends ISkinSimple {
public boolean handwritten();
public String getSvgLinkTarget();
public int getTabSize();
public int maxAsciiMessageLength();
public int colorArrowSeparationSpace();
public SplitParam getSplitParam();
public int swimlaneWidth();
}

View File

@ -92,7 +92,9 @@ public class NewpagedDiagram extends AbstractPSystem {
return diagrams.size();
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
return diagrams.get(num).exportDiagram(os, 0, fileFormat);
}

View File

@ -46,6 +46,7 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
import net.sourceforge.plantuml.preproc.Defines;
import net.sourceforge.plantuml.stats.StatsUtils;
public class Option {
@ -249,6 +250,20 @@ public class Option {
OptionFlags.getInstance().setUseSuggestEngine(false);
} else if (s.equalsIgnoreCase("-printfonts")) {
OptionFlags.getInstance().setPrintFonts(true);
} else if (s.equalsIgnoreCase("-dumphtmlstats")) {
OptionFlags.getInstance().setDumpHtmlStats(true);
} else if (s.equalsIgnoreCase("-dumpstats")) {
OptionFlags.getInstance().setDumpStats(true);
} else if (s.equalsIgnoreCase("-loopstats")) {
OptionFlags.getInstance().setLoopStats(true);
} else if (s.equalsIgnoreCase("-htmlstats")) {
StatsUtils.setHtmlStats(true);
} else if (s.equalsIgnoreCase("-xmlstats")) {
StatsUtils.setXmlStats(true);
} else if (s.equalsIgnoreCase("-realtimestats")) {
StatsUtils.setRealTimeStats(true);
} else if (s.equalsIgnoreCase("-useseparatorminus")) {
OptionFlags.getInstance().setFileSeparator("-");
} else if (StringUtils.goLowerCase(s).startsWith("-ftp")) {
final int x = s.indexOf(':');
if (x == -1) {

View File

@ -109,8 +109,10 @@ public class OptionFlags {
private boolean checkDotError;
private boolean printFonts;
private boolean useSuggestEngine;
// private boolean failOnError;
private boolean encodesprite;
private boolean dumpHtmlStats;
private boolean dumpStats;
private boolean loopStats;
private boolean overwrite;
private String fileSeparator = "_";
private File logData;
@ -123,14 +125,6 @@ public class OptionFlags {
return singleton;
}
// public synchronized final boolean isKeepTmpFiles() {
// return keepTmpFiles;
// }
//
// public synchronized final void setKeepTmpFiles(boolean keepTmpFiles) {
// this.keepTmpFiles = keepTmpFiles;
// }
public final boolean isVerbose() {
return verbose;
}
@ -225,17 +219,6 @@ public class OptionFlags {
}
}
// public static void logErrorFile(final PSystemError systemError, PrintStream ps) {
// ps.println(systemError.getDescription());
// for (CharSequence t : systemError.getTitle()) {
// ps.println(t);
// }
// systemError.print(ps);
// for (String s : systemError.getSuggest()) {
// ps.println(s);
// }
// }
public final void setLogData(File logData) {
this.logData = logData;
logData.delete();
@ -269,14 +252,6 @@ public class OptionFlags {
this.useSuggestEngine = useSuggestEngine;
}
// public final boolean isFailOnError() {
// return failOnError;
// }
//
// public final void setFailOnError(boolean failOnError) {
// this.failOnError = failOnError;
// }
public final boolean isEncodesprite() {
return encodesprite;
}
@ -293,12 +268,36 @@ public class OptionFlags {
this.overwrite = overwrite;
}
public String getFileSeparator() {
public final String getFileSeparator() {
return fileSeparator;
}
public void setFileSeparator(String fileSeparator) {
public final void setFileSeparator(String fileSeparator) {
this.fileSeparator = fileSeparator;
}
public final boolean isDumpHtmlStats() {
return dumpHtmlStats;
}
public final void setDumpHtmlStats(boolean value) {
this.dumpHtmlStats = value;
}
public final boolean isDumpStats() {
return dumpStats;
}
public final void setDumpStats(boolean dumpStats) {
this.dumpStats = dumpStats;
}
public final boolean isLoopStats() {
return loopStats;
}
public final void setLoopStats(boolean loopStats) {
this.loopStats = loopStats;
}
}

View File

@ -119,6 +119,9 @@ public class OptionPrint {
System.out.println(" -author[s]\t\tTo print information about PlantUML authors");
System.out.println(" -overwrite\t\tTo allow to overwrite read only files");
System.out.println(" -printfonts\t\tTo print fonts available on your system");
System.out.println(" -htmlstats\t\tTo output general statistics in file plantuml-stats.html");
System.out.println(" -xmlstats\t\tTo output general statistics in file plantuml-stats.xml");
System.out.println(" -realtimestats\tTo generate statistics on the fly rather than at the end");
System.out.println();
System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT.");
exit();
@ -156,9 +159,12 @@ public class OptionPrint {
public static Collection<String> interestingProperties() {
final Properties p = System.getProperties();
final List<String> all = Arrays.asList("java.runtime.name", "Java Runtime", "java.vm.name", "JVM",
"java.runtime.version", "Java Version", "os.name", "Operating System", "os.version", "OS Version",
"file.encoding", "Default Encoding", "user.language", "Language", "user.country", "Country");
final List<String> all = withIp() ? Arrays.asList("java.runtime.name", "Java Runtime", "java.vm.name", "JVM",
"java.runtime.version", "Java Version", "os.name", "Operating System", "file.encoding",
"Default Encoding", "user.language", "Language", "user.country", "Country") : Arrays.asList(
"java.runtime.name", "Java Runtime", "java.vm.name", "JVM", "java.runtime.version", "Java Version",
"os.name", "Operating System", "os.version", "OS Version", "file.encoding", "Default Encoding",
"user.language", "Language", "user.country", "Country");
final List<String> result = new ArrayList<String>();
for (int i = 0; i < all.size(); i += 2) {
result.add(all.get(i + 1) + ": " + p.getProperty(all.get(i)));
@ -168,7 +174,9 @@ public class OptionPrint {
public static Collection<String> interestingValues() {
final List<String> strings = new ArrayList<String>();
strings.add("Machine: " + getHostName());
if (withIp() == false) {
strings.add("Machine: " + getHostName());
}
strings.add("PLANTUML_LIMIT_SIZE: " + GraphvizUtils.getenvImageLimit());
strings.add("Processors: " + Runtime.getRuntime().availableProcessors());
final long freeMemory = Runtime.getRuntime().freeMemory();
@ -184,6 +192,10 @@ public class OptionPrint {
return Collections.unmodifiableCollection(strings);
}
private static boolean withIp() {
return getHostName().startsWith("ip-");
}
private static String hostname;
public static synchronized String getHostName() {

View File

@ -71,8 +71,7 @@ import net.sourceforge.plantuml.project2.PSystemProjectFactory2;
import net.sourceforge.plantuml.salt.PSystemSaltFactory;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.statediagram.StateDiagramFactory;
import net.sourceforge.plantuml.stats.PSystemStatsFactory;
import net.sourceforge.plantuml.stats.StatsUtils;
import net.sourceforge.plantuml.stats.StatsUtilsIncrement;
import net.sourceforge.plantuml.sudoku.PSystemSudokuFactory;
import net.sourceforge.plantuml.ugraphic.sprite.PSystemListInternalSpritesFactory;
import net.sourceforge.plantuml.version.License;
@ -111,7 +110,7 @@ public class PSystemBuilder {
return err;
} finally {
if (result != null) {
StatsUtils.onceMoreParse(System.currentTimeMillis() - now, result.getClass());
StatsUtilsIncrement.onceMoreParse(System.currentTimeMillis() - now, result.getClass());
}
}
@ -150,7 +149,7 @@ public class PSystemBuilder {
factories.add(new PSystemSudokuFactory());
}
factories.add(new PSystemMathFactory(DiagramType.MATH));
factories.add(new PSystemStatsFactory());
// factories.add(new PSystemStatsFactory());
factories.add(new PSystemCreoleFactory());
factories.add(new PSystemEggFactory());
factories.add(new PSystemAppleTwoFactory());

View File

@ -99,7 +99,9 @@ public class PSystemError extends AbstractPSystem {
return "red";
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
if (fileFormat.getFileFormat() == FileFormat.ATXT || fileFormat.getFileFormat() == FileFormat.UTXT) {
final UGraphicTxt ugt = new UGraphicTxt();
final UmlCharArea area = ugt.getCharArea();

View File

@ -47,30 +47,24 @@ import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.html.CucaDiagramHtmlMaker;
import net.sourceforge.plantuml.png.PngSplitter;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.stats.StatsUtils;
public class PSystemUtils {
public static List<File> exportDiagrams(Diagram system, File suggestedFile, FileFormatOption fileFormatOption)
throws IOException {
final long now = System.currentTimeMillis();
try {
if (system instanceof NewpagedDiagram) {
return exportDiagramsNewpaged((NewpagedDiagram) system, suggestedFile, fileFormatOption);
}
if (system instanceof SequenceDiagram) {
return exportDiagramsSequence((SequenceDiagram) system, suggestedFile, fileFormatOption);
}
if (system instanceof CucaDiagram) {
return exportDiagramsCuca((CucaDiagram) system, suggestedFile, fileFormatOption);
}
if (system instanceof ActivityDiagram3) {
return exportDiagramsActivityDiagram3((ActivityDiagram3) system, suggestedFile, fileFormatOption);
}
return exportDiagramsDefault(system, suggestedFile, fileFormatOption);
} finally {
StatsUtils.onceMoreGenerate(System.currentTimeMillis() - now, system.getClass(), fileFormatOption.getFileFormat());
if (system instanceof NewpagedDiagram) {
return exportDiagramsNewpaged((NewpagedDiagram) system, suggestedFile, fileFormatOption);
}
if (system instanceof SequenceDiagram) {
return exportDiagramsSequence((SequenceDiagram) system, suggestedFile, fileFormatOption);
}
if (system instanceof CucaDiagram) {
return exportDiagramsCuca((CucaDiagram) system, suggestedFile, fileFormatOption);
}
if (system instanceof ActivityDiagram3) {
return exportDiagramsActivityDiagram3((ActivityDiagram3) system, suggestedFile, fileFormatOption);
}
return exportDiagramsDefault(system, suggestedFile, fileFormatOption);
}
private static List<File> exportDiagramsNewpaged(NewpagedDiagram system, File suggestedFile,

View File

@ -63,6 +63,7 @@ import net.sourceforge.plantuml.png.MetadataTag;
import net.sourceforge.plantuml.preproc.Defines;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.statediagram.StateDiagramFactory;
import net.sourceforge.plantuml.stats.StatsUtils;
import net.sourceforge.plantuml.swing.MainWindow2;
import net.sourceforge.plantuml.ugraphic.sprite.SpriteGrayLevel;
import net.sourceforge.plantuml.ugraphic.sprite.SpriteUtils;
@ -73,6 +74,18 @@ public class Run {
public static void main(String[] argsArray) throws IOException, InterruptedException {
final long start = System.currentTimeMillis();
final Option option = new Option(argsArray);
if (OptionFlags.getInstance().isDumpStats()) {
StatsUtils.dumpStats();
return;
}
if (OptionFlags.getInstance().isLoopStats()) {
StatsUtils.loopStats();
return;
}
if (OptionFlags.getInstance().isDumpHtmlStats()) {
StatsUtils.outHtml();
return;
}
if (OptionFlags.getInstance().isEncodesprite()) {
encodeSprite(option.getResult());
return;

View File

@ -792,4 +792,15 @@ public class SkinParam implements ISkinParam {
margin);
}
public int swimlaneWidth() {
final String value = getValue("swimlanewidth");
if ("same".equalsIgnoreCase(value)) {
return -1;
}
if (value != null && value.matches("\\d+")) {
return Integer.parseInt(value);
}
return 0;
}
}

View File

@ -242,4 +242,8 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getSplitParam();
}
public int swimlaneWidth() {
return skinParam.swimlaneWidth();
}
}

View File

@ -30,7 +30,6 @@
*/
package net.sourceforge.plantuml;
import java.awt.Font;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
@ -73,7 +72,6 @@ import net.sourceforge.plantuml.svek.GraphvizCrash;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UTranslate;
@ -213,7 +211,8 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann
this.hideUnlinkedData = hideUnlinkedData;
}
final public ImageData exportDiagram(OutputStream os, int index, FileFormatOption fileFormatOption)
@Override
final protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
fileFormatOption = fileFormatOption.withSvgLinkTarget(getSkinParam().getSvgLinkTarget());

View File

@ -73,8 +73,10 @@ public class PSystemXearth extends AbstractPSystem {
this.config = config;
this.markers = markers;
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final ACearth earth = new ACearth(markers);
final ConfigurationACearth conf = earth.getConf();
conf.setInt("imageWidth", width);
@ -102,7 +104,6 @@ public class PSystemXearth extends AbstractPSystem {
return new ImageDataSimple(width, height);
}
private Date extractGmt(String s) {
final SimpleDateFormat timeFormat;
if (s.matches("\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
@ -125,5 +126,4 @@ public class PSystemXearth extends AbstractPSystem {
return new DiagramDescriptionImpl("(XEarth)", getClass());
}
}

View File

@ -136,6 +136,11 @@ public class ActivityDiagram3 extends UmlDiagram {
current().add(new InstructionStop(swinlanes.getCurrentSwimlane(), nextLinkRenderer()));
}
public void breakInstruction() {
manageSwimlaneStrategy();
current().add(new InstructionBreak(swinlanes.getCurrentSwimlane(), nextLinkRenderer()));
}
public void end() {
manageSwimlaneStrategy();
current().add(new InstructionEnd(swinlanes.getCurrentSwimlane(), nextLinkRenderer()));
@ -165,8 +170,9 @@ public class ActivityDiagram3 extends UmlDiagram {
final double margin = 10;
final double dpiFactor = getDpiFactor(fileFormatOption, Dimension2DDouble.delta(dim, 2 * margin, 0));
final ImageBuilder imageBuilder = new ImageBuilder(getSkinParam(), dpiFactor, fileFormatOption.isWithMetadata() ? getMetadata()
: null, getWarningOrError(), margin, margin, getAnimation());
final ImageBuilder imageBuilder = new ImageBuilder(getSkinParam(), dpiFactor,
fileFormatOption.isWithMetadata() ? getMetadata() : null, getWarningOrError(), margin, margin,
getAnimation());
imageBuilder.setUDrawable(result);
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os);

View File

@ -38,6 +38,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandActivityLegacy1;
import net.sourceforge.plantuml.activitydiagram3.command.CommandActivityLong3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandArrow3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandArrowLong3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandBreak;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElse3;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElseIf2;
import net.sourceforge.plantuml.activitydiagram3.command.CommandElseLegacy1;
@ -118,6 +119,7 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory {
// cmds.add(new CommandGroupEnd3());
cmds.add(new CommandStart3());
cmds.add(new CommandStop3());
cmds.add(new CommandBreak());
cmds.add(new CommandEnd3());
cmds.add(new CommandKill3());
cmds.add(new CommandLink3());

View File

@ -36,6 +36,7 @@ import net.sourceforge.plantuml.ISkinParam;
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.activitydiagram3.ftile.WeldingPoint;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.Rainbow;
@ -70,6 +71,11 @@ public class Branch {
this.labelPositive = labelPositive;
this.color = color;
}
public Collection<WeldingPoint> getWeldingPoints() {
return ftile.getWeldingPoints();
}
public void add(Instruction ins) {
list.add(ins);

View File

@ -0,0 +1,66 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.activitydiagram3;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileBreak;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
public class InstructionBreak extends MonoSwimable implements Instruction {
private final LinkRendering inlinkRendering;
public InstructionBreak(Swimlane swimlane, LinkRendering inlinkRendering) {
super(swimlane);
this.inlinkRendering = inlinkRendering;
if (inlinkRendering == null) {
throw new IllegalArgumentException();
}
}
public Ftile createFtile(FtileFactory factory) {
return new FtileBreak(factory.skinParam(), getSwimlaneIn());
}
public void add(Instruction other) {
throw new UnsupportedOperationException();
}
final public boolean kill() {
return false;
}
public LinkRendering getInLinkRendering() {
return inlinkRendering;
}
}

View File

@ -51,7 +51,7 @@ public class InstructionGroup implements Instruction, InstructionCollection {
private final LinkRendering linkRendering;
private final Display test;
private Display headerNote = Display.NULL;
private PositionedNote note = null;
public InstructionGroup(Instruction parent, Display test, HtmlColor backColor, HtmlColor titleColor,
Swimlane swimlane, HtmlColor borderColor, LinkRendering linkRendering) {
@ -69,7 +69,7 @@ public class InstructionGroup implements Instruction, InstructionCollection {
}
public Ftile createFtile(FtileFactory factory) {
return factory.createGroup(list.createFtile(factory), test, backColor, titleColor, headerNote, borderColor);
return factory.createGroup(list.createFtile(factory), test, backColor, titleColor, note, borderColor);
}
public Instruction getParent() {
@ -86,7 +86,7 @@ public class InstructionGroup implements Instruction, InstructionCollection {
public boolean addNote(Display note, NotePosition position, NoteType type, Colors colors) {
if (list.isEmpty()) {
this.headerNote = note;
this.note = new PositionedNote(note, position, type, colors);
return true;
}
return list.addNote(note, position, type, colors);

View File

@ -38,8 +38,10 @@ import java.util.Set;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileDecorateWelding;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.WeldingPoint;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileWithNoteOpale;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HtmlColor;
@ -91,6 +93,14 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
if (getPositionedNotes().size() > 0) {
result = FtileWithNoteOpale.create(result, getPositionedNotes(), skinParam, false);
}
final List<WeldingPoint> weldingPoints = new ArrayList<WeldingPoint>();
for (Branch branch : thens) {
weldingPoints.addAll(branch.getWeldingPoints());
}
weldingPoints.addAll(elseBranch.getWeldingPoints());
if (weldingPoints.size() > 0) {
result = new FtileDecorateWelding(result, weldingPoints);
}
return result;
}

View File

@ -37,9 +37,11 @@ import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileDecorateWelding;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileEmpty;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.WeldingPoint;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
@ -75,9 +77,11 @@ public class InstructionList extends WithNote implements Instruction, Instructio
if (all.size() == 0) {
return new FtileEmpty(factory.skinParam(), defaultSwimlane);
}
final List<WeldingPoint> breaks = new ArrayList<WeldingPoint>();
Ftile result = eventuallyAddNote(factory, null, getSwimlaneIn());
for (Instruction ins : all) {
Ftile cur = ins.createFtile(factory);
breaks.addAll(cur.getWeldingPoints());
if (ins.getInLinkRendering().isNone() == false) {
cur = factory.decorateIn(cur, ins.getInLinkRendering());
}
@ -91,6 +95,10 @@ public class InstructionList extends WithNote implements Instruction, Instructio
if (outlinkRendering != null) {
result = factory.decorateOut(result, outlinkRendering);
}
if (breaks.size() > 0) {
result = new FtileDecorateWelding(result, breaks);
}
// if (killed) {
// result = new FtileKilled(result);
// }
@ -128,15 +136,15 @@ public class InstructionList extends WithNote implements Instruction, Instructio
public Swimlane getSwimlaneIn() {
return defaultSwimlane;
// final Set<Swimlane> swimlanes = getSwimlanes();
// if (swimlanes.size() == 0) {
// return null;
// }
// if (swimlanes.size() == 1) {
// return swimlanes.iterator().next();
// }
// System.err.println("foo1="+getClass());
// return all.get(0).getSwimlaneIn();
// final Set<Swimlane> swimlanes = getSwimlanes();
// if (swimlanes.size() == 0) {
// return null;
// }
// if (swimlanes.size() == 1) {
// return swimlanes.iterator().next();
// }
// System.err.println("foo1="+getClass());
// return all.get(0).getSwimlaneIn();
}
public Swimlane getSwimlaneOut() {

View File

@ -0,0 +1,59 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.activitydiagram3.command;
import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
public class CommandBreak extends SingleLineCommand2<ActivityDiagram3> {
public CommandBreak() {
super(getRegexConcat());
}
static RegexConcat getRegexConcat() {
return new RegexConcat(//
new RegexLeaf("^"), //
new RegexLeaf("break"), //
new RegexLeaf(";?$"));
}
@Override
protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, RegexResult arg) {
diagram.breakInstruction();
return CommandExecutionResult.ok();
}
}

View File

@ -32,6 +32,7 @@ package net.sourceforge.plantuml.activitydiagram3.ftile;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
@ -87,4 +88,8 @@ public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
return thickness;
}
public List<WeldingPoint> getWeldingPoints() {
return Collections.emptyList();
}
}

View File

@ -212,7 +212,7 @@ public class CollisionDetector implements UGraphic {
this.context.manageSnakes = manageSnakes;
}
public boolean isSpecialTxt() {
public boolean matchesProperty(String propertyName) {
return false;
}

View File

@ -31,6 +31,7 @@
package net.sourceforge.plantuml.activitydiagram3.ftile;
import java.util.Collection;
import java.util.List;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
@ -55,4 +56,6 @@ public interface Ftile extends Swimable, TextBlock {
public Collection<Connection> getInnerConnections();
public List<WeldingPoint> getWeldingPoints();
}

View File

@ -31,9 +31,11 @@
package net.sourceforge.plantuml.activitydiagram3.ftile;
import java.awt.geom.Dimension2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.ISkinParam;
@ -139,4 +141,10 @@ public class FtileAssemblySimple extends AbstractTextBlock implements Ftile {
return tile1.getThickness();
}
public List<WeldingPoint> getWeldingPoints() {
final List<WeldingPoint> result = new ArrayList<WeldingPoint>(tile1.getWeldingPoints());
result.addAll(tile2.getWeldingPoints());
return Collections.unmodifiableList(result);
}
}

View File

@ -0,0 +1,54 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.activitydiagram3.ftile;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.graphic.StringBounder;
public class FtileBreak extends FtileEmpty implements WeldingPoint {
public FtileBreak(ISkinParam skinParam, Swimlane swimlane) {
super(skinParam, swimlane);
}
public FtileGeometry calculateDimension(StringBounder stringBounder) {
return super.calculateDimension(stringBounder).withoutPointOut();
}
@Override
public List<WeldingPoint> getWeldingPoints() {
return Collections.singletonList((WeldingPoint) this);
}
}

View File

@ -0,0 +1,53 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.activitydiagram3.ftile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDecorate;
public class FtileDecorateWelding extends FtileDecorate {
private final List<WeldingPoint> breaks;
public FtileDecorateWelding(final Ftile ftile, final List<WeldingPoint> breaks) {
super(ftile);
this.breaks = new ArrayList<WeldingPoint>(breaks);
}
@Override
public List<WeldingPoint> getWeldingPoints() {
return Collections.unmodifiableList(breaks);
}
}

View File

@ -80,7 +80,7 @@ public interface FtileFactory {
public Ftile createSplit(List<Ftile> all);
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, Display headerNote,
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, PositionedNote note,
HtmlColor borderColor);
}

View File

@ -156,9 +156,9 @@ public class FtileFactoryDelegator implements FtileFactory {
return factory.createSplit(all);
}
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, Display headerNote,
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, PositionedNote note,
HtmlColor borderColor) {
return factory.createGroup(list, name, backColor, titleColor, headerNote, borderColor);
return factory.createGroup(list, name, backColor, titleColor, note, borderColor);
}
public StringBounder getStringBounder() {

View File

@ -36,6 +36,7 @@ import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class Swimlane implements SpecificBackcolorable {
@ -98,4 +99,14 @@ public class Swimlane implements SpecificBackcolorable {
this.colors = colors;
}
private MinMax minMax;
public void setMinMax(MinMax minMax) {
this.minMax = minMax;
}
public MinMax getMinMax() {
return minMax;
}
}

View File

@ -81,6 +81,7 @@ import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.utils.MathUtils;
public class Swimlanes extends AbstractTextBlock implements TextBlock {
@ -272,7 +273,50 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
cross.flushUg();
}
private void computeDrawingWidths(UGraphic ug, TextBlock full) {
final StringBounder stringBounder = ug.getStringBounder();
for (Swimlane swimlane : swimlanes) {
final LimitFinder limitFinder = new LimitFinder(stringBounder, false);
final UGraphicInterceptorOneSwimlane interceptor = new UGraphicInterceptorOneSwimlane(new UGraphicForSnake(
limitFinder), swimlane);
full.drawU(interceptor);
interceptor.flushUg();
final MinMax minMax = limitFinder.getMinMax();
swimlane.setMinMax(minMax);
}
}
private void computeSize(UGraphic ug, TextBlock full) {
computeDrawingWidths(ug, full);
double x1 = 0;
final StringBounder stringBounder = ug.getStringBounder();
double swimlaneWidth = skinParam.swimlaneWidth();
if (swimlaneWidth == -1) {
for (Swimlane swimlane : swimlanes) {
final MinMax minMax = swimlane.getMinMax();
swimlaneWidth = Math.max(swimlaneWidth, minMax.getWidth());
}
}
for (Swimlane swimlane : swimlanes) {
final MinMax minMax = swimlane.getMinMax();
final double drawingWidth = minMax.getWidth() + 2 * separationMargin;
final TextBlock swTitle = swimlane.getDisplay().create(getFontConfiguration(), HorizontalAlignment.LEFT,
skinParam);
final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth();
final double totalWidth = MathUtils.max(swimlaneWidth, drawingWidth, titleWidth + 2 * separationMargin);
final UTranslate translate = new UTranslate(x1 - minMax.getMinX() + separationMargin
+ (totalWidth - drawingWidth) / 2.0, 0);
swimlane.setTranslateAndWidth(translate, totalWidth);
x1 += totalWidth;
}
}
private void computeSizeOld(UGraphic ug, TextBlock full) {
double x1 = 0;
final StringBounder stringBounder = ug.getStringBounder();
for (Swimlane swimlane : swimlanes) {

View File

@ -0,0 +1,35 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.activitydiagram3.ftile;
public interface WeldingPoint {
}

View File

@ -30,7 +30,10 @@
*/
package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
import java.util.Collections;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.activitydiagram3.PositionedNote;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactoryDelegator;
@ -47,10 +50,14 @@ public class FtileFactoryDelegatorCreateGroup extends FtileFactoryDelegator {
}
@Override
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, Display headerNote,
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, PositionedNote note,
HtmlColor borderColor) {
final HtmlColor arrowColor = rose.getHtmlColor(skinParam(), ColorParam.activityArrow);
return new FtileGroup(list, name, headerNote, arrowColor, backColor, titleColor, skinParam(), borderColor);
Ftile result = new FtileGroup(list, name, null, arrowColor, backColor, titleColor, skinParam(), borderColor);
if (note != null) {
result = new FtileWithNotes(result, Collections.singleton(note), skinParam());
}
return result;
}
}

View File

@ -30,19 +30,25 @@
*/
package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
import java.util.List;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileBreak;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactoryDelegator;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.WeldingPoint;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileDiamond;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorAndStyle;
import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
@ -53,6 +59,7 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
@Override
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Ftile repeat, Display test, Display yes, Display out,
HtmlColor color, LinkRendering backRepeatLinkRendering) {
final ConditionStyle conditionStyle = skinParam().getConditionStyle();
final HtmlColor borderColor = getRose().getHtmlColor(skinParam(), ColorParam.activityBorder);
@ -66,7 +73,21 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
final FontConfiguration fcDiamond = new FontConfiguration(skinParam(), FontParam.ACTIVITY_DIAMOND, null);
final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ACTIVITY_ARROW, null);
return FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, repeat, test, yes, out, borderColor,
backColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(), fcDiamond, fcArrow);
Ftile result = FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, repeat, test, yes, out,
borderColor, backColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(), fcDiamond,
fcArrow);
final List<WeldingPoint> weldingPoints = repeat.getWeldingPoints();
if (weldingPoints.size() > 0) {
final Ftile diamondBreak = new FtileDiamond(repeat.skinParam(), backColor, borderColor, swimlane);
result = assembly(result, diamondBreak);
final FtileBreak ftileBreak = (FtileBreak) weldingPoints.get(0);
System.err.println("break=" + ftileBreak);
final UTranslate pos = repeat.getTranslateFor(ftileBreak, getStringBounder());
System.err.println("pos=" + pos);
}
return result;
}
}

View File

@ -68,10 +68,8 @@ public class FtileGroup extends AbstractFtile {
private final Ftile inner;
private final TextBlock name;
private final TextBlock headerNote;
// private final HtmlColor arrowColor;
private final HtmlColor borderColor;
private final HtmlColor backColor;
// private final HtmlColor titleColor;
private final UStroke stroke;
public FtileGroup(Ftile inner, Display title, Display displayNote, HtmlColor arrowColor, HtmlColor backColor,
@ -79,8 +77,6 @@ public class FtileGroup extends AbstractFtile {
super(inner.skinParam());
this.backColor = backColor == null ? HtmlColorUtils.WHITE : backColor;
this.inner = FtileUtils.addHorizontalMargin(inner, 10);
// this.arrowColor = arrowColor;
// this.titleColor = titleColor;
this.borderColor = backColor == null ? HtmlColorUtils.BLACK : borderColor;
final UFont font = skinParam.getFont(null, false, FontParam.PARTITION);

View File

@ -47,6 +47,8 @@ import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.creole.CreoleParser;
import net.sourceforge.plantuml.creole.Sheet;
import net.sourceforge.plantuml.creole.SheetBlock1;
import net.sourceforge.plantuml.creole.SheetBlock2;
import net.sourceforge.plantuml.creole.Stencil;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
@ -57,10 +59,11 @@ import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.svek.image.Opale;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.utils.MathUtils;
public class FtileWithNotes extends AbstractFtile /* implements Stencil */{
public class FtileWithNotes extends AbstractFtile {
private final Ftile tile;
@ -83,9 +86,6 @@ public class FtileWithNotes extends AbstractFtile /* implements Stencil */{
public FtileWithNotes(Ftile tile, Collection<PositionedNote> notes, ISkinParam skinParam) {
super(tile.skinParam());
// if (note.getColors() != null) {
// skinParam = note.getColors().mute(skinParam);
// }
this.tile = tile;
final Rose rose = new Rose();
@ -99,20 +99,30 @@ public class FtileWithNotes extends AbstractFtile /* implements Stencil */{
final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT),
skinParam, CreoleMode.FULL).createSheet(note.getDisplay());
final SheetBlock1 sheet1 = new SheetBlock1(sheet, 0, skinParam.getPadding());
final SheetBlock2 sheet2 = new SheetBlock2(sheet1, new Stencil() {
// -6 and 15 value comes from Opale: this is very ugly!
public double getStartingX(StringBounder stringBounder, double y) {
return -6;
}
final TextBlock opale = TextBlockUtils.withMargin(new Opale(borderColor, noteBackgroundColor, sheet1,
skinParam.shadowing(), false), 10, 10);
public double getEndingX(StringBounder stringBounder, double y) {
return sheet1.getEndingX(stringBounder, y) + 15;
}
}, new UStroke());
final Opale opale = new Opale(borderColor, noteBackgroundColor, sheet2, skinParam.shadowing(), false);
final TextBlock opaleMarged = TextBlockUtils.withMargin(opale, 10, 10);
if (note.getNotePosition() == NotePosition.LEFT) {
if (left == null) {
left = opale;
left = opaleMarged;
} else {
left = TextBlockUtils.mergeTB(left, opale, HorizontalAlignment.CENTER);
left = TextBlockUtils.mergeTB(left, opaleMarged, HorizontalAlignment.CENTER);
}
} else {
if (right == null) {
right = opale;
right = opaleMarged;
} else {
right = TextBlockUtils.mergeTB(right, opale, HorizontalAlignment.CENTER);
right = TextBlockUtils.mergeTB(right, opaleMarged, HorizontalAlignment.CENTER);
}
}
}
@ -176,12 +186,4 @@ public class FtileWithNotes extends AbstractFtile /* implements Stencil */{
return new Dimension2DDouble(dimTile.getWidth() + dimLeft.getWidth() + dimRight.getWidth(), height);
}
// public double getStartingX(StringBounder stringBounder, double y) {
// return -opale.getMarginX1();
// }
//
// public double getEndingX(StringBounder stringBounder, double y) {
// return opale.calculateDimension(stringBounder).getWidth() - opale.getMarginX1();
// }
}

View File

@ -137,7 +137,7 @@ public class VCompactFactory implements FtileFactory {
return new FtileForkInner(all);
}
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, Display headerNote,
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, PositionedNote note,
HtmlColor borderColor) {
return list;
}

View File

@ -31,6 +31,7 @@
package net.sourceforge.plantuml.activitydiagram3.ftile.vertical;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.ISkinParam;
@ -39,6 +40,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Connection;
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.WeldingPoint;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -105,5 +107,10 @@ public abstract class FtileDecorate extends AbstractTextBlock implements Ftile {
protected final Ftile getFtileDelegated() {
return ftile;
}
public List<WeldingPoint> getWeldingPoints() {
return ftile.getWeldingPoints();
}
}

View File

@ -48,6 +48,7 @@ import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.SourceFileReader;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
import net.sourceforge.plantuml.preproc.Defines;
import net.sourceforge.plantuml.stats.StatsUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
@ -374,4 +375,19 @@ public class PlantUmlTask extends Task {
OptionFlags.getInstance().setFileSeparator(s);
}
public void setHtmlStats(String s) {
final boolean flag = "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s);
StatsUtils.setHtmlStats(flag);
}
public void setXmlStats(String s) {
final boolean flag = "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s);
StatsUtils.setXmlStats(flag);
}
public void setRealTimeStats(String s) {
final boolean flag = "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s);
StatsUtils.setRealTimeStats(flag);
}
}

View File

@ -23,52 +23,103 @@
*/
package net.sourceforge.plantuml.api;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.prefs.Preferences;
import net.sourceforge.plantuml.Log;
public class NumberAnalyzed implements INumberAnalyzed {
private static final int SLIDING_WINDOW = 512;
private long nb;
private long sum;
private long min;
private long max;
private long sumOfSquare;
// See https://fossies.org/linux/haproxy/include/proto/freq_ctr.h
private long sliddingSum;
private final String name;
private final Lock saveLock = new ReentrantLock();
public NumberAnalyzed(String name) {
this.name = name;
}
public synchronized void reset() {
this.nb = 0;
this.sum = 0;
this.min = 0;
this.max = 0;
this.sumOfSquare = 0;
this.sliddingSum = 0;
}
public NumberAnalyzed() {
this("");
}
public void save(Preferences prefs) {
public final void save(Preferences prefs) {
if (name.length() == 0) {
throw new UnsupportedOperationException();
}
prefs.putLong(name + ".nb", nb);
prefs.putLong(name + ".sum", sum);
prefs.putLong(name + ".min", min);
prefs.putLong(name + ".max", max);
if (saveLock.tryLock())
try {
prefs.put(name + ".saved", getSavedString());
} finally {
saveLock.unlock();
}
}
private String getSavedString() {
final long nb1;
final long sum1;
final long min1;
final long max1;
final long sumOfSquare1;
final long sliddingSum1;
final String supp1;
synchronized (this) {
nb1 = nb;
sum1 = sum;
min1 = min;
max1 = max;
sumOfSquare1 = sumOfSquare;
sliddingSum1 = sliddingSum;
}
supp1 = getSavedSupplementatyData();
return longToString(nb1) + ";" + longToString(sum1) + ";" + longToString(min1) + ";" + longToString(max1) + ";"
+ longToString(sumOfSquare1) + ";" + longToString(sliddingSum1) + ";" + supp1 + ";";
}
protected String getSavedSupplementatyData() {
return "";
}
protected final String longToString(long val) {
return Long.toString(val, 36);
}
public static NumberAnalyzed load(String name, Preferences prefs) {
final long nb = prefs.getLong(name + ".nb", 0);
if (nb == 0) {
final String value = prefs.get(name + ".saved", "");
if (value.length() == 0) {
Log.info("Cannot load " + name);
return null;
}
final long sum = prefs.getLong(name + ".sum", 0);
if (sum == 0) {
try {
final StringTokenizer st = new StringTokenizer(value, ";");
return new NumberAnalyzed(name, Long.parseLong(st.nextToken(), 36), Long.parseLong(st.nextToken(), 36),
Long.parseLong(st.nextToken(), 36), Long.parseLong(st.nextToken(), 36), Long.parseLong(
st.nextToken(), 36), Long.parseLong(st.nextToken(), 36));
} catch (Exception e) {
e.printStackTrace();
Log.info("Error reading " + value);
return null;
}
final long min = prefs.getLong(name + ".min", 0);
if (min == 0) {
return null;
}
final long max = prefs.getLong(name + ".max", 0);
if (max == 0) {
return null;
}
return new NumberAnalyzed(name, nb, sum, min, max);
}
@Override
@ -76,42 +127,59 @@ public class NumberAnalyzed implements INumberAnalyzed {
return "sum=" + sum + " nb=" + nb + " min=" + min + " max=" + max + " mean=" + getMean();
}
private NumberAnalyzed(String name, long nb, long sum, long min, long max) {
protected NumberAnalyzed(String name, long nb, long sum, long min, long max, long sumOfSquare, long sliddingSum) {
this(name);
this.nb = nb;
this.sum = sum;
this.min = min;
this.max = max;
this.sumOfSquare = sumOfSquare;
this.sliddingSum = sliddingSum;
}
public synchronized INumberAnalyzed getCopyImmutable() {
final NumberAnalyzed copy = new NumberAnalyzed(name, nb, sum, min, max);
final NumberAnalyzed copy = new NumberAnalyzed(name, nb, sum, min, max, sumOfSquare, sliddingSum);
return copy;
}
public synchronized void addValue(long v) {
nb++;
if (nb == 1) {
sum = v;
min = v;
max = v;
return;
} else if (v > max) {
max = v;
} else if (v < min) {
min = v;
}
sum += v;
if (v > max) {
max = v;
}
if (v < min) {
min = v;
}
sumOfSquare += v * v;
sliddingSum = sliddingSum * (SLIDING_WINDOW - 1) / SLIDING_WINDOW + v;
}
public synchronized void add(NumberAnalyzed other) {
public void add(NumberAnalyzed other) {
final long nb1;
final long sum1;
final long min1;
final long max1;
final long sumOfSquare1;
final long sliddingSum1;
synchronized (other) {
this.sum += other.sum;
this.nb += other.nb;
this.min = Math.min(this.min, other.min);
this.max = Math.max(this.max, other.max);
nb1 = other.nb;
sum1 = other.sum;
min1 = other.min;
max1 = other.max;
sumOfSquare1 = other.sumOfSquare;
sliddingSum1 = other.sliddingSum;
}
synchronized (this) {
this.sum += sum1;
this.nb += nb1;
this.min = Math.min(this.min, min1);
this.max = Math.max(this.max, max1);
this.sumOfSquare += sumOfSquare1;
// Not good!
this.sliddingSum += sliddingSum1;
}
}
@ -138,7 +206,23 @@ public class NumberAnalyzed implements INumberAnalyzed {
return sum / nb;
}
public String getName() {
public final long getStandardDeviation() {
final long sum1;
final long sumOfSquare1;
final long nb1;
synchronized (this) {
sum1 = this.sum;
sumOfSquare1 = this.sumOfSquare;
nb1 = this.nb;
}
if (nb1 == 0) {
return 0;
}
final long mean = sum1 / nb1;
return Math.round(Math.sqrt(sumOfSquare1 / nb1 - mean * mean));
}
final public String getName() {
return name;
}

View File

@ -0,0 +1,167 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* Project Info: http://plantuml.com
*
* 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License aint with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package net.sourceforge.plantuml.api;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicLong;
import java.util.prefs.Preferences;
import net.sourceforge.plantuml.Log;
public class NumberAnalyzed2 implements INumberAnalyzed {
private static final int SLIDING_WINDOW = 512;
private final AtomicLong nb = new AtomicLong();
private final AtomicLong sum = new AtomicLong();
private final AtomicLong min = new AtomicLong();
private final AtomicLong max = new AtomicLong();
private final AtomicLong sumOfSquare = new AtomicLong();
// See https://fossies.org/linux/haproxy/include/proto/freq_ctr.h
private final AtomicLong sliddingSum = new AtomicLong();
private final String name;
public NumberAnalyzed2(String name) {
this.name = name;
}
public void reset() {
this.nb.set(0);
this.sum.set(0);
this.min.set(0);
this.max.set(0);
this.sumOfSquare.set(0);
this.sliddingSum.set(0);
}
public NumberAnalyzed2() {
this("");
}
public final void save(Preferences prefs) {
if (name.length() == 0) {
throw new UnsupportedOperationException();
}
prefs.put(name + ".saved", getSavedString());
}
protected String getSavedString() {
final String value = longToString(nb) + ";" + longToString(sum) + ";" + longToString(min) + ";"
+ longToString(max) + ";" + longToString(sumOfSquare) + ";" + longToString(sliddingSum);
return value;
}
protected final String longToString(AtomicLong val) {
return Long.toString(val.get(), 36);
}
public static NumberAnalyzed2 load(String name, Preferences prefs) {
final String value = prefs.get(name + ".saved", "");
if (value.length() == 0) {
System.err.println("Cannot load " + name);
return null;
}
try {
final StringTokenizer st = new StringTokenizer(value, ";");
return new NumberAnalyzed2(name, Long.parseLong(st.nextToken(), 36), Long.parseLong(st.nextToken(), 36),
Long.parseLong(st.nextToken(), 36), Long.parseLong(st.nextToken(), 36), Long.parseLong(
st.nextToken(), 36), Long.parseLong(st.nextToken(), 36));
} catch (Exception e) {
e.printStackTrace();
Log.info("Error reading " + value);
return null;
}
}
@Override
public String toString() {
return "sum=" + sum + " nb=" + nb + " min=" + min + " max=" + max + " mean=" + getMean();
}
protected NumberAnalyzed2(String name, long nb, long sum, long min, long max, long sumOfSquare, long sliddingSum) {
this(name);
this.nb.set(nb);
this.sum.set(sum);
this.min.set(min);
this.max.set(max);
this.sumOfSquare.set(sumOfSquare);
this.sliddingSum.set(sliddingSum);
}
public INumberAnalyzed getCopyImmutable() {
final NumberAnalyzed2 copy = new NumberAnalyzed2(name, nb.get(), sum.get(), min.get(), max.get(),
sumOfSquare.get(), sliddingSum.get());
return copy;
}
public void addValue(long v) {
nb.incrementAndGet();
if (nb.get() == 1) {
min.set(v);
max.set(v);
} else if (v > max.get()) {
max.set(v);
} else if (v < min.get()) {
min.set(v);
}
sum.addAndGet(v);
sumOfSquare.addAndGet(v * v);
sliddingSum.set(sliddingSum.get() * (SLIDING_WINDOW - 1) / SLIDING_WINDOW + v);
}
public void add(NumberAnalyzed2 other) {
this.sum.addAndGet(other.sum.get());
this.nb.addAndGet(other.nb.get());
this.min.set(Math.min(this.min.get(), other.min.get()));
this.max.set(Math.max(this.max.get(), other.max.get()));
}
public final long getNb() {
return nb.get();
}
public final long getSum() {
return sum.get();
}
public final long getMin() {
return min.get();
}
public final long getMax() {
return max.get();
}
public final long getMean() {
if (nb.get() == 0) {
return 0;
}
return sum.get() / nb.get();
}
final public String getName() {
return name;
}
}

View File

@ -0,0 +1,122 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* Project Info: http://plantuml.com
*
* 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License aint with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package net.sourceforge.plantuml.api;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicLong;
import java.util.prefs.Preferences;
import net.sourceforge.plantuml.Log;
public class NumberAnalyzedDated extends NumberAnalyzed {
private final AtomicLong created = new AtomicLong();
private final AtomicLong modified = new AtomicLong();
private String comment;
private NumberAnalyzedDated(String name, long nb, long sum, long min, long max, long sumOfSquare, long sliddingSum,
long created, long modified, String comment) {
super(name, nb, sum, min, max, sumOfSquare, sliddingSum);
this.created.set(created);
this.modified.set(modified);
this.comment = comment;
}
@Override
public synchronized void reset() {
super.reset();
resetCreatedModifiedComment();
}
public NumberAnalyzedDated() {
super();
resetCreatedModifiedComment();
}
public NumberAnalyzedDated(String name) {
super(name);
resetCreatedModifiedComment();
}
private void resetCreatedModifiedComment() {
final long now = System.currentTimeMillis();
this.created.set(now);
this.modified.set(now);
this.comment = " ";
};
@Override
public void addValue(long v) {
super.addValue(v);
this.modified.set(System.currentTimeMillis());
}
@Override
public void add(NumberAnalyzed other) {
super.add(other);
this.modified.set(System.currentTimeMillis());
}
@Override
protected String getSavedSupplementatyData() {
return longToString(created.get()) + ";" + longToString(modified.get()) + ";" + comment;
}
public static NumberAnalyzedDated load(String name, Preferences prefs) {
final String value = prefs.get(name + ".saved", "");
if (value.length() == 0) {
Log.info("Cannot load " + name);
return null;
}
try {
final StringTokenizer st = new StringTokenizer(value, ";");
return new NumberAnalyzedDated(name, Long.parseLong(st.nextToken(), 36),
Long.parseLong(st.nextToken(), 36), Long.parseLong(st.nextToken(), 36), Long.parseLong(
st.nextToken(), 36), Long.parseLong(st.nextToken(), 36),
Long.parseLong(st.nextToken(), 36), Long.parseLong(st.nextToken(), 36), Long.parseLong(
st.nextToken(), 36), st.nextToken());
} catch (Exception e) {
e.printStackTrace();
Log.info("Error reading " + value);
return null;
}
}
final public long getCreationTime() {
return created.get();
}
final public long getModificationTime() {
return modified.get();
}
final public synchronized String getComment() {
return comment;
}
final public synchronized void setComment(String comment) {
this.comment = comment;
}
}

View File

@ -80,7 +80,7 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
new RegexConcat(
//
new RegexLeaf("ARROW_HEAD1", "([%s]+[ox]|[#\\[<*+^]|[<\\[]\\|)?"), //
new RegexLeaf("ARROW_HEAD1", "([%s]+[ox]|[#\\[<*+^}]|[<\\[]\\|)?"), //
new RegexLeaf("ARROW_BODY1", "([-=.]+)"), //
new RegexLeaf("ARROW_STYLE1",
"(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden|norank)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden|,norank)*)\\])?"),
@ -89,7 +89,7 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
new RegexLeaf("ARROW_STYLE2",
"(?:\\[((?:#\\w+|dotted|dashed|plain|bold|hidden|norank)(?:,#\\w+|,dotted|,dashed|,plain|,bold|,hidden|,norank)*)\\])?"),
new RegexLeaf("ARROW_BODY2", "([-=.]*)"), //
new RegexLeaf("ARROW_HEAD2", "([ox][%s]+|[#\\]>*+^]|\\|[>\\]])?")), //
new RegexLeaf("ARROW_HEAD2", "([ox][%s]+|[#\\]>*+^{]|\\|[>\\]])?")), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("SECOND_LABEL", "(?:[%g]([^%g]+)[%g])?"),
@ -415,6 +415,9 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
if ("<|".equals(s)) {
return LinkDecor.EXTENDS;
}
if ("}".equals(s)) {
return LinkDecor.CROWFOOT;
}
if ("<".equals(s)) {
return LinkDecor.ARROW;
}
@ -450,6 +453,9 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
if (">".equals(s)) {
return LinkDecor.ARROW;
}
if ("{".equals(s)) {
return LinkDecor.CROWFOOT;
}
if ("^".equals(s)) {
return LinkDecor.EXTENDS;
}

View File

@ -0,0 +1,94 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.creole;
import java.awt.Color;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorSimple;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.math.AsciiMathSafe;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UImageSvg;
public class AtomMath implements Atom {
private final double scale = 1;
private final AsciiMathSafe math;
private final HtmlColor foreground;
public AtomMath(AsciiMathSafe math, HtmlColor foreground) {
this.math = math;
this.foreground = foreground;
}
private Dimension2D calculateDimensionSlow(StringBounder stringBounder) {
final BufferedImage image = math.getImage(Color.BLACK, Color.WHITE);
return new Dimension2DDouble(image.getWidth() * scale, image.getHeight() * scale);
}
private Dimension2D dim;
public Dimension2D calculateDimension(StringBounder stringBounder) {
if (dim == null) {
dim = calculateDimensionSlow(stringBounder);
}
return dim;
}
public double getStartingAltitude(StringBounder stringBounder) {
return 0;
}
public void drawU(UGraphic ug) {
final boolean isSvg = ug.matchesProperty("SVG");
final Color back = getColor(ug.getParam().getBackcolor(), Color.WHITE);
final Color fore = getColor(foreground, Color.BLACK);
if (isSvg) {
final String svg = math.getSvg(fore, back);
ug.draw(new UImageSvg(svg));
} else {
ug.draw(new UImage(math.getImage(fore, back), scale));
}
}
private Color getColor(HtmlColor color, Color defaultValue) {
if (color instanceof HtmlColorSimple) {
return ((HtmlColorSimple) color).getColor999();
}
return defaultValue;
}
}

View File

@ -37,6 +37,7 @@ import java.util.List;
import java.util.Map;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
@ -104,18 +105,33 @@ public class AtomTable implements Atom {
.apply(new UTranslate(x1, y1)).draw(new URectangle(x2 - x1, y2 - y1));
}
for (int j = 0; j < getNbCols(); j++) {
if (j >= line.cells.size()) {
continue;
}
final Atom cell = line.cells.get(j);
HorizontalAlignment align = HorizontalAlignment.LEFT;
if (cell instanceof SheetBlock1) {
align = ((SheetBlock1) cell).getCellAlignment();
}
final HtmlColor cellBackColor = line.cellsBackColor.get(j);
final double x1 = getStartingX(j);
final double x2 = getStartingX(j + 1);
final double cellWidth = x2 - x1;
if (cellBackColor != null) {
final double y1 = getStartingY(i);
final double y2 = getStartingY(i + 1);
final double x1 = getStartingX(j);
final double x2 = getStartingX(j + 1);
ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(cellBackColor))
.apply(new UTranslate(x1, y1)).draw(new URectangle(x2 - x1, y2 - y1));
}
final Position pos = positions.get(cell);
cell.drawU(ug.apply(pos.getTranslate()));
final Dimension2D dimCell = cell.calculateDimension(ug.getStringBounder());
final double dx;
if (align == HorizontalAlignment.RIGHT) {
dx = cellWidth - dimCell.getWidth();
} else {
dx = 0;
}
cell.drawU(ug.apply(pos.getTranslate().compose(new UTranslate(dx, 0))));
}
}
ug = ug.apply(new UChangeColor(lineColor));

View File

@ -167,7 +167,7 @@ public class AtomText implements Atom {
}
public void drawU(UGraphic ug) {
if (ug.isSpecialTxt()) {
if (ug.matchesProperty("SPECIALTXT")) {
ug.draw(this);
return;
}

View File

@ -0,0 +1,69 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.graphic.Splitter;
import net.sourceforge.plantuml.math.AsciiMathSafe;
public class CommandCreoleMath implements Command {
private final Pattern2 pattern;
private CommandCreoleMath(String p) {
this.pattern = MyPattern.cmpile(p);
}
public static Command create() {
return new CommandCreoleMath("^(?i)(" + Splitter.mathPattern + ")");
}
public int matchingSize(String line) {
final Matcher2 m = pattern.matcher(line);
if (m.find() == false) {
return 0;
}
return m.group(1).length();
}
public String executeAndGetRemaining(String line, StripeSimple stripe) {
final Matcher2 m = pattern.matcher(line);
if (m.find() == false) {
throw new IllegalStateException();
}
final String math = m.group(2);
stripe.addMath(new AsciiMathSafe(math));
return line.substring(m.group(1).length());
}
}

View File

@ -63,7 +63,9 @@ public class PSystemCreole extends AbstractPSystem {
lines.add(line);
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final Display display = Display.create(lines);
final UFont font = new UFont("Serif", Font.PLAIN, 14);
final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(font);

View File

@ -63,6 +63,17 @@ public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, S
this.padding = padding;
}
public HorizontalAlignment getCellAlignment() {
if (stripes.size() != 1) {
return HorizontalAlignment.LEFT;
}
final Stripe simple = stripes.get(0);
if (simple instanceof StripeSimple) {
return ((StripeSimple) simple).getCellAlignment();
}
return HorizontalAlignment.LEFT;
}
private void initMap(StringBounder stringBounder) {
if (positions != null) {
return;
@ -127,13 +138,12 @@ public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, S
initMap(stringBounder);
return Dimension2DDouble.delta(minMax.getDimension(), 2 * padding);
}
@Override
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) {
return null;
}
public void drawU(UGraphic ug) {
initMap(ug.getStringBounder());
if (padding > 0) {
@ -159,5 +169,5 @@ public class SheetBlock1 extends AbstractTextBlock implements TextBlock, Atom, S
public double getEndingX(StringBounder stringBounder, double y) {
return calculateDimension(stringBounder).getWidth();
}
}

View File

@ -61,7 +61,7 @@ public class SheetBlock2 extends AbstractTextBlock implements TextBlock, Atom {
public void drawU(UGraphic ug) {
if (stencil != null) {
ug = new UGraphicStencil(ug, stencil, defaultStroke);
ug = UGraphicStencil.create(ug, stencil, defaultStroke);
}
block.drawU(ug);
}

View File

@ -30,6 +30,7 @@
*/
package net.sourceforge.plantuml.creole;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -39,7 +40,11 @@ import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.FontPosition;
import net.sourceforge.plantuml.graphic.FontStyle;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorSimple;
import net.sourceforge.plantuml.graphic.ImgValign;
import net.sourceforge.plantuml.math.AsciiMathSafe;
import net.sourceforge.plantuml.openiconic.OpenIcon;
import net.sourceforge.plantuml.ugraphic.sprite.Sprite;
import net.sourceforge.plantuml.utils.CharHidder;
@ -48,6 +53,15 @@ public class StripeSimple implements Stripe {
final private List<Atom> atoms = new ArrayList<Atom>();
final private List<Command> commands = new ArrayList<Command>();
private HorizontalAlignment align = HorizontalAlignment.LEFT;
public void setCellAlignment(HorizontalAlignment align) {
this.align = align;
}
public HorizontalAlignment getCellAlignment() {
return align;
}
private FontConfiguration fontConfiguration;
@ -90,6 +104,7 @@ public class StripeSimple implements Stripe {
this.commands.add(CommandCreoleExposantChange.create(FontPosition.INDICE));
this.commands.add(CommandCreoleImg.create());
this.commands.add(CommandCreoleOpenIcon.create());
this.commands.add(CommandCreoleMath.create());
this.commands.add(CommandCreoleSprite.create());
this.commands.add(CommandCreoleSpace.create());
this.commands.add(CommandCreoleFontFamilyChange.create());
@ -160,6 +175,10 @@ public class StripeSimple implements Stripe {
}
}
public void addMath(AsciiMathSafe math) {
atoms.add(new AtomMath(math, fontConfiguration.getColor()));
}
private void modifyStripe(String line) {
final StringBuilder pending = new StringBuilder();

View File

@ -113,6 +113,10 @@ public class StripeTable implements Stripe {
for (String s : lines) {
final StripeSimple cell = new StripeSimple(getFontConfiguration(mode), stripeStyle,
new CreoleContext(), skinParam, CreoleMode.FULL);
if (s.startsWith("<r>")) {
cell.setCellAlignment(HorizontalAlignment.RIGHT);
s = s.substring("<r>".length());
}
cell.analyzeAndAdd(s);
cells.add(cell);
}

View File

@ -38,6 +38,7 @@ import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryArrowAndCircle;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryCircle;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryCircleConnect;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryCircleCross;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryCrowfoot;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryDiamond;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryNotNavigable;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryParenthesis;
@ -50,7 +51,7 @@ public enum LinkDecor {
NONE(2, false, 0), EXTENDS(30, false, 2), COMPOSITION(15, true, 1.3), AGREGATION(15, false, 1.3), NOT_NAVIGABLE(1,
false, 0.1),
ARROW(10, true, 0.5), ARROW_TRIANGLE(10, true, 0.8), ARROW_AND_CIRCLE(10, false, 0.5),
CROWFOOT(10, true, 0.8), ARROW(10, true, 0.5), ARROW_TRIANGLE(10, true, 0.8), ARROW_AND_CIRCLE(10, false, 0.5),
CIRCLE(0, false, 0.5), CIRCLE_CONNECT(0, false, 0.5), PARENTHESIS(0, false, OptionFlags.USE_INTERFACE_EYE2 ? 0.5
: 1.0), SQUARRE(0, false, 0.5),
@ -84,6 +85,8 @@ public enum LinkDecor {
return new ExtremityFactoryPlus();
} else if (this == LinkDecor.ARROW_TRIANGLE) {
return new ExtremityFactoryTriangle();
} else if (this == LinkDecor.CROWFOOT) {
return new ExtremityFactoryCrowfoot();
} else if (this == LinkDecor.CIRCLE_CROSS) {
return new ExtremityFactoryCircleCross();
} else if (this == LinkDecor.ARROW) {

View File

@ -59,7 +59,7 @@ public class PSystemCute extends AbstractPSystem {
public void doCommandLine(String line) {
line = StringUtils.trin(line);
if (line.length()==0 || line.startsWith("'")) {
if (line.length() == 0 || line.startsWith("'")) {
return;
}
if (line.startsWith("group ")) {
@ -79,8 +79,11 @@ public class PSystemCute extends AbstractPSystem {
}
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 10, 10, null, false);
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 10, 10, null,
false);
builder.setUDrawable(root);
return builder.writeImageTOBEMOVED(fileFormat, os);
}

View File

@ -56,7 +56,9 @@ public class PSystemDedication extends AbstractPSystem {
this.keepLetter = keepLetter;
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE,
getMetadata(), null, 0, 0, null, false);
imageBuilder.setUDrawable(new UDrawable() {

View File

@ -63,7 +63,9 @@ public class PSystemDot extends AbstractPSystem {
return new DiagramDescriptionImpl("(Dot)", getClass());
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final Graphviz graphviz = GraphvizUtils.create(null, data,
StringUtils.goLowerCase(fileFormat.getFileFormat().name()));
if (graphviz.getExeState() != ExeState.OK) {

View File

@ -64,14 +64,17 @@ public class PSystemDitaa extends AbstractPSystem {
}
PSystemDitaa add(String line) {
return new PSystemDitaa(data + line + "\n", processingOptions.performSeparationOfCommonEdges(), dropShadows, scale);
return new PSystemDitaa(data + line + "\n", processingOptions.performSeparationOfCommonEdges(), dropShadows,
scale);
}
public DiagramDescription getDescription() {
return new DiagramDescriptionImpl("(Ditaa)", getClass());
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
if (fileFormat.getFileFormat() == FileFormat.ATXT) {
os.write(getSource().getPlainString().getBytes());
return new ImageDataSimple();

View File

@ -30,9 +30,11 @@
*/
package net.sourceforge.plantuml.donors;
import java.awt.geom.Dimension2D;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
@ -43,44 +45,66 @@ import net.sourceforge.plantuml.code.TranscoderImpl;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.DiagramDescriptionImpl;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.graphic.GraphicPosition;
import net.sourceforge.plantuml.graphic.GraphicStrings;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.version.PSystemVersion;
public class PSystemDonors extends AbstractPSystem {
public static final String DONORS = "UDfTKqjosp0CtUCKN6lIGoXsxDQ_PAmqdSaEbX29DaMe9ELKFbjtlLYXj3BfS2MC0F3zc9li_o47JnJ8gTm6jXfBUAOi7cvXmx5q7l9f50-mTF4N3L3G0NtGQDME6mkvhTYf9LEuqFZvzYOTKpjQs61oaGqmrrEX3UHnDP-Xw2E40POwkpsMOJMXx3qKWRg6h9enTy9lFjr37jRjfr5sC6EZhTfpxmbM_QV_sP65o5Hq6hO9QcpJKgxA3Vr2MucSiqRBrXhT84ptLzgsXbsAFbpWqUYp3CnrUHBarp_QmeE_hhO9Y8pECB-qEhX1RR3X2c4rYlxQeAnF-Z8oqIuvfq5aiXYaJ_09hjK_y7IwOMKhALqfcYpmu8OJl_kJbaL6nXvTq1Vu6hihXgqk6pBg7hKPKWRcaeBn7bQ4ziiAovyzUJNl3mx5InFvll0nKDcejKEF4L9D4j74iVSnMTAYrdpMQL0-el8z4jO8-oIyunKfp-meqrqIApwDojopGukckrEl590x3tiXYAvIQprQ2ml3RjHx--UtCH-cnq2O99mIfyqrJWudjKVNcrj6Fad8QDeJJc7PwnlukT6gGApa8RcQr0-oDRaxjSsVlnLv37h65fPqyu1I7MmfWMdLYt2OIuJNiTFHwBCydGqHF9pJTt16sCKbr4uWiuJKijUIahubjU2UGbIxzB18VVhW4hDXBwc80dUdQqbKeLlu2u2IDTa0";
public static final String DONORS = "UDfTKyjosp0ClEChUDQa7w7OiLk_ah7IT2OtM88jsXJXafHI-TjwwuyLSYkJ3a_4401t5ulSPFyFENYXG4xbDh3LMC8hPV5m0okEeVEGZwMuWxcBJzH3GJlqGQDL6wujvBPYf-PCuKB3TR-NZ34TBQmm-SW6cEenq0Ros9exADe8eOUvpkwFPLYCA5iFHQ1pJLPDcC_2Rph-GnwMpQTITZ1XewtQSki95ksdz-p8GcGCpXhM2Mfiqb2-oWtzGbk9d9DQIzS3kbwORc-qxG4sAVfmWMUZEocOwl8ao6ylsiAJlxMs2OYCEfXU6XrShrPOSuMm64H_hr7Q9taPcJWkEQTUPB8O94_m2Qx5F_1qkcDbAmbTAPhCSEVw4t_uavP6HigUNT0N-1gpAuQrBciowX6rwLC6vfA2yHuMXFRB0ikVBNarRNSEPPOcydtZOw2oLak77YEa0ub5aubz3CwI5BNaJgT6kLhbUoIi4RQ9UOSlKfxPKQhFYQtuD2Zpo0ujclE3UgU0VFQm5OBeAhNKmsXXPjWDUg___3RcElHe29EOK-oqkjd9uQZsCFNwdf5F738CxGL7ispr7VpSQ5KWLh98xa3g1za3kGUrpb-_5NaqUiOMvdItGAaEjXJ3DEfDE4p5mikOwMYOiwpEYWYUkdGFEeHDR4BD239BICrRBIvf6r8pRYb4jKiFitHELoxH6_QIYYXmD_eWZYfq4nTI0CbUxmVTKNRyBzppFBC0";
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final UDrawable result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE,
getMetadata(), null, 0, 0, null, false);
imageBuilder.setUDrawable(result);
return imageBuilder.writeImageTOBEMOVED(fileFormat, os);
}
private TextBlockBackcolored getGraphicStrings() throws IOException {
final List<String> lines = new ArrayList<String>();
lines.add("<b>Special thanks to our sponsors and donors !");
lines.add(" ");
int i = 0;
final List<String> donors = getDonors();
final int maxLine = (donors.size() + 1) / 2;
for (String d : donors) {
lines.add(d);
i++;
if (i == maxLine) {
lines.add(" ");
lines.add(" ");
i = 0;
private UDrawable getGraphicStrings() throws IOException {
final List<TextBlock> cols = getCols(getDonors(), 3, 5);
return new UDrawable() {
public void drawU(UGraphic ug) {
final TextBlockBackcolored header = GraphicStrings.createBlackOnWhite(Arrays
.asList("<b>Special thanks to our sponsors and donors !"));
header.drawU(ug);
final StringBounder stringBounder = ug.getStringBounder();
ug = ug.apply(new UTranslate(0, header.calculateDimension(stringBounder).getHeight()));
double x = 0;
double lastX = 0;
double y = 0;
for (TextBlock tb : cols) {
final Dimension2D dim = tb.calculateDimension(stringBounder);
tb.drawU(ug.apply(new UTranslate(x, 0)));
lastX = x;
x += dim.getWidth() + 10;
y = Math.max(y, dim.getHeight());
}
final UImage logo = new UImage(PSystemVersion.getPlantumlImage());
ug.apply(new UTranslate(lastX, y - logo.getHeight())).draw(logo);
}
};
}
public static List<TextBlock> getCols(List<String> lines, final int nbCol, final int reserved) throws IOException {
final List<TextBlock> result = new ArrayList<TextBlock>();
final int maxLine = (lines.size() + (nbCol - 1) + reserved) / nbCol;
for (int i = 0; i < lines.size(); i += maxLine) {
final List<String> current = lines.subList(i, Math.min(lines.size(), i + maxLine));
result.add(GraphicStrings.createBlackOnWhite(current));
}
lines.add(" ");
return GraphicStrings.createBlackOnWhite(lines, PSystemVersion.getPlantumlImage(),
GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT, maxLine + 2);
return result;
}
private List<String> getDonors() throws IOException {

View File

@ -65,7 +65,9 @@ public class PSystemAppleTwo extends AbstractPSystem {
is.close();
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);

View File

@ -54,7 +54,9 @@ public class PSystemCharlie extends AbstractPSystem {
image = PSystemVersion.getCharlieImage();
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.BLACK,
getMetadata(), null, 0, 0, null, false);
imageBuilder.setUDrawable(new UDrawable() {

View File

@ -57,7 +57,9 @@ public class PSystemEgg extends AbstractPSystem {
}
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);

View File

@ -72,7 +72,9 @@ public class PSystemEmpty extends AbstractPSystem {
strings.add(" ");
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);
@ -82,8 +84,8 @@ public class PSystemEmpty extends AbstractPSystem {
}
private TextBlockBackcolored getGraphicStrings() throws IOException {
final TextBlockBackcolored result = GraphicStrings.createBlackOnWhite(strings, PSystemVersion.getPlantumlImage(),
GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT);
final TextBlockBackcolored result = GraphicStrings.createBlackOnWhite(strings,
PSystemVersion.getPlantumlImage(), GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT);
return result;
}

View File

@ -53,7 +53,7 @@ public class PSystemLost extends AbstractPSystem {
strings.add("Thank you for choosing Oceanic Airlines.");
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);

View File

@ -41,15 +41,16 @@ import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
public class PSystemPath extends AbstractPSystem {
private final GraphicsPath path;
public PSystemPath(String s) {
this.path = new GraphicsPath(new ColorMapperIdentity(), s);
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
return path.writeImage(os);
}
@ -57,7 +58,4 @@ public class PSystemPath extends AbstractPSystem {
return new DiagramDescriptionImpl("(Path)", getClass());
}
}

View File

@ -73,7 +73,9 @@ public class PSystemRIP extends AbstractPSystem {
is.close();
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);

View File

@ -65,7 +65,9 @@ public class PSystemListFonts extends AbstractPSystem {
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);

View File

@ -67,8 +67,6 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage {
private final GraphicPosition position;
private int maxLine = 0;
public static IEntityImage createForError(List<String> strings, boolean useRed) {
if (useRed) {
return new GraphicStrings(strings, new UFont("SansSerif", Font.BOLD, 14), HtmlColorUtils.BLACK,
@ -90,14 +88,6 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage {
return new GraphicStrings(strings, monospaced14(), HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, null, null);
}
public static TextBlockBackcolored createBlackOnWhite(List<String> strings, BufferedImage image,
GraphicPosition position, int maxLine) {
final GraphicStrings result = new GraphicStrings(strings, sansSerif12(), HtmlColorUtils.BLACK,
HtmlColorUtils.WHITE, image, position);
result.maxLine = maxLine;
return result;
}
public static TextBlockBackcolored createBlackOnWhite(List<String> strings, BufferedImage image,
GraphicPosition position) {
return new GraphicStrings(strings, sansSerif12(), HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, image, position);
@ -123,24 +113,9 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage {
private TextBlock getTextBlock() {
TextBlock result = null;
if (maxLine == 0) {
result = Display.create(strings).create(
new FontConfiguration(font, maincolor, hyperlinkColor, useUnderlineForHyperlink),
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
} else {
for (int i = 0; i < strings.size(); i += maxLine) {
final int n = Math.min(i + maxLine, strings.size());
final TextBlock textBlock1 = Display.create(strings.subList(i, n)).create(
new FontConfiguration(font, maincolor, hyperlinkColor, useUnderlineForHyperlink),
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
if (result == null) {
result = textBlock1;
} else {
result = TextBlockUtils.withMargin(result, 0, 10, 0, 0);
result = TextBlockUtils.mergeLR(result, textBlock1, VerticalAlignment.TOP);
}
}
}
result = Display.create(strings).create(
new FontConfiguration(font, maincolor, hyperlinkColor, useUnderlineForHyperlink),
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
// result = DateEventUtils.addEvent(result, green);
return result;
}

View File

@ -64,6 +64,7 @@ public class Splitter {
static final String htmlTag;
static final String linkPattern = "\\[\\[([^\\[\\]]+)\\]\\]";
public static final String mathPattern = "\\<math\\>(.+?)\\</math\\>";
private static final Pattern2 tagOrText;
@ -99,8 +100,8 @@ public class Splitter {
sb.append('|');
sb.append(fontFamilyPattern);
sb.append('|');
sb.append(spritePattern);
sb.append('|');
// sb.append(spritePattern);
// sb.append('|');
sb.append(linkPattern);
sb.append('|');
sb.append(svgAttributePattern);

View File

@ -31,40 +31,52 @@
package net.sourceforge.plantuml.graphic;
import java.awt.geom.Dimension2D;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
class TextBlockHorizontal extends AbstractTextBlock implements TextBlock {
public class TextBlockHorizontal extends AbstractTextBlock implements TextBlock {
private final TextBlock b1;
private final TextBlock b2;
private final List<TextBlock> blocks = new ArrayList<TextBlock>();
private final VerticalAlignment alignment;
TextBlockHorizontal(TextBlock b1, TextBlock b2, VerticalAlignment alignment) {
this.b1 = b1;
this.b2 = b2;
this.blocks.add(b1);
this.blocks.add(b2);
this.alignment = alignment;
}
public TextBlockHorizontal(List<TextBlock> all, VerticalAlignment alignment) {
if (all.size() < 2) {
throw new IllegalArgumentException();
}
this.blocks.addAll(all);
this.alignment = alignment;
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
final Dimension2D dim1 = b1.calculateDimension(stringBounder);
final Dimension2D dim2 = b2.calculateDimension(stringBounder);
return Dimension2DDouble.mergeLR(dim1, dim2);
Dimension2D dim = blocks.get(0).calculateDimension(stringBounder);
for (int i = 1; i < blocks.size(); i++) {
dim = Dimension2DDouble.mergeLR(dim, blocks.get(i).calculateDimension(stringBounder));
}
return dim;
}
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
final Dimension2D dimb1 = b1.calculateDimension(ug.getStringBounder());
final Dimension2D dimb2 = b2.calculateDimension(ug.getStringBounder());
final Dimension2D dim1 = b1.calculateDimension(ug.getStringBounder());
if (alignment == VerticalAlignment.CENTER) {
b1.drawU(ug.apply(new UTranslate(0, ((dim.getHeight() - dimb1.getHeight()) / 2))));
b2.drawU(ug.apply(new UTranslate(dim1.getWidth(), ((dim.getHeight() - dimb2.getHeight()) / 2))));
} else {
b1.drawU(ug);
b2.drawU(ug.apply(new UTranslate(dim1.getWidth(), 0)));
double x = 0;
final Dimension2D dimtotal = calculateDimension(ug.getStringBounder());
for (TextBlock block : blocks) {
final Dimension2D dimb = block.calculateDimension(ug.getStringBounder());
if (alignment == VerticalAlignment.CENTER) {
final double dy = (dimtotal.getHeight() - dimb.getHeight()) / 2;
block.drawU(ug.apply(new UTranslate(x, dy)));
} else {
block.drawU(ug.apply(new UTranslate(x, 0)));
}
x += dimb.getWidth();
}
}

View File

@ -40,8 +40,8 @@ public abstract class UGraphicDelegator implements UGraphic {
final private UGraphic ug;
public final boolean isSpecialTxt() {
return ug.isSpecialTxt();
public final boolean matchesProperty(String propertyName) {
return ug.matchesProperty(propertyName);
}

View File

@ -94,7 +94,7 @@ class USymbolArtifact extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = new UGraphicStencil(ug, getRectangleStencil(dim), new UStroke());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawArtifact(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();

View File

@ -90,7 +90,7 @@ class USymbolCloud extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = new UGraphicStencil(ug, getRectangleStencil(dim), new UStroke());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawCloud(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();

View File

@ -34,8 +34,10 @@ import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicStencil;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
class USymbolComponent1 extends USymbol {
@ -45,7 +47,6 @@ class USymbolComponent1 extends USymbol {
return SkinParameter.COMPONENT1;
}
private void drawNode(UGraphic ug, double widthTotal, double heightTotal, boolean shadowing) {
final URectangle form = new URectangle(widthTotal, heightTotal);
@ -66,12 +67,14 @@ class USymbolComponent1 extends USymbol {
return new Margin(10, 10, 10, 10);
}
public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, final SymbolContext symbolContext) {
public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype,
final SymbolContext symbolContext) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder();
final Dimension2D dimTotal = calculateDimension(stringBounder);
ug = UGraphicStencil.create(ug, getRectangleStencil(dimTotal), new UStroke());
ug = symbolContext.apply(ug);
drawNode(ug, dimTotal.getWidth(), dimTotal.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();
@ -92,4 +95,9 @@ class USymbolComponent1 extends USymbol {
throw new UnsupportedOperationException();
}
@Override
public boolean manageHorizontalLine() {
return true;
}
}

View File

@ -34,8 +34,10 @@ import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicStencil;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
class USymbolComponent2 extends USymbol {
@ -74,6 +76,7 @@ class USymbolComponent2 extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawNode(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();
@ -114,4 +117,9 @@ class USymbolComponent2 extends USymbol {
};
}
@Override
public boolean manageHorizontalLine() {
return true;
}
}

View File

@ -81,7 +81,7 @@ class USymbolFile extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = new UGraphicStencil(ug, getRectangleStencil(dim), new UStroke());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawFile(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();

View File

@ -109,7 +109,7 @@ public class USymbolFolder extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = new UGraphicStencil(ug, getRectangleStencil(dim), new UStroke());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
final Dimension2D dimName = name.calculateDimension(ug.getStringBounder());
drawFolder(ug, dim.getWidth(), dim.getHeight(), dimName, symbolContext.isShadowing());

View File

@ -95,7 +95,7 @@ class USymbolFrame extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = new UGraphicStencil(ug, getRectangleStencil(dim), new UStroke());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawFrame(ug, dim.getWidth(), dim.getHeight(), new Dimension2DDouble(0, 0), symbolContext.isShadowing());
final Margin margin = getMargin();

View File

@ -33,6 +33,7 @@ package net.sourceforge.plantuml.graphic;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.creole.Stencil;
import net.sourceforge.plantuml.ugraphic.AbstractUGraphicHorizontalLine;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -47,10 +48,9 @@ class USymbolQueue extends USymbol {
return SkinParameter.QUEUE;
}
private final double dx = 5;
private void drawDatabase(UGraphic ug, double width, double height, boolean shadowing) {
private void drawQueue(UGraphic ug, double width, double height, boolean shadowing) {
final UPath shape = new UPath();
if (shadowing) {
shape.setDeltaShadow(3.0);
@ -79,48 +79,61 @@ class USymbolQueue extends USymbol {
return closing;
}
class MyUGraphicDatabase extends AbstractUGraphicHorizontalLine {
class MyUGraphicQueue extends AbstractUGraphicHorizontalLine implements Stencil {
private final double endingX;
private final double x1;
private final double x2;
private final double fullHeight;
@Override
protected AbstractUGraphicHorizontalLine copy(UGraphic ug) {
return new MyUGraphicDatabase(ug, endingX);
return new MyUGraphicQueue(ug, x1, x2, fullHeight);
}
public MyUGraphicDatabase(UGraphic ug, double endingX) {
public MyUGraphicQueue(UGraphic ug, double x1, double x2, double fullHeight) {
super(ug);
this.endingX = endingX;
this.x1 = x1;
this.x2 = x2;
this.fullHeight = fullHeight;
}
@Override
protected void drawHline(UGraphic ug, UHorizontalLine line, UTranslate translate) {
// final UPath closing = getClosingPath(endingX);
// ug = ug.apply(translate);
// ug.apply(line.getStroke()).apply(new UChangeBackColor(null)).apply(new UTranslate(0, -15)).draw(closing);
// if (line.isDouble()) {
// ug.apply(line.getStroke()).apply(new UChangeBackColor(null)).apply(new UTranslate(0, -15 + 2))
// .draw(closing);
// }
line.drawTitleInternal(ug, 0, endingX, 0, true);
line.drawLineInternal(ug, this, translate.getDy(), line.getStroke());
}
public double getStartingX(StringBounder stringBounder, double y) {
return 0;
}
public double getEndingX(StringBounder stringBounder, double y) {
final double factor2;
final double halfHeight = fullHeight / 2;
if (y <= halfHeight) {
factor2 = 1 - (y / halfHeight);
} else {
factor2 = (y - halfHeight) / halfHeight;
}
return (x2 - x1) * factor2 + x1;
}
}
private Margin getMargin() {
return new Margin(5, 15, 5, 5);
}
public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, final SymbolContext symbolContext) {
public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype,
final SymbolContext symbolContext) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = symbolContext.apply(ug);
drawDatabase(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
drawQueue(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();
final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, HorizontalAlignment.CENTER);
final UGraphic ug2 = new MyUGraphicDatabase(ug, dim.getWidth());
final UGraphic ug2 = new MyUGraphicQueue(ug, dim.getWidth() - 2 * dx, dim.getWidth() - dx,
dim.getHeight());
tb.drawU(ug2.apply(new UTranslate(margin.getX1(), margin.getY1())));
}
@ -160,9 +173,4 @@ class USymbolQueue extends USymbol {
return true;
}
// @Override
// public int suppHeightBecauseOfShape() {
// return 15;
// }
}

View File

@ -34,7 +34,9 @@ import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicStencil;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
class USymbolRect extends USymbol {
@ -75,6 +77,7 @@ class USymbolRect extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawRect(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();
@ -119,4 +122,9 @@ class USymbolRect extends USymbol {
};
}
@Override
public boolean manageHorizontalLine() {
return true;
}
}

View File

@ -63,7 +63,7 @@ class USymbolStorage extends USymbol {
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = new UGraphicStencil(ug, getRectangleStencil(dim), new UStroke());
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
ug = symbolContext.apply(ug);
drawStorage(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Margin margin = getMargin();

View File

@ -60,7 +60,9 @@ public class PSystemJcckit extends AbstractPSystem {
prop = new PropertiesBasedConfigData(p);
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Sets up a Graphics2DPlotCanvas

View File

@ -58,7 +58,9 @@ public class PSystemTree extends AbstractPSystem {
return new DiagramDescriptionImpl("(Tree)", getClass());
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE, null, null,
5, 5, null, false);
if (rendering == Rendering.NEEDLE) {

View File

@ -56,7 +56,9 @@ public class PSystemLogo extends AbstractPSystem {
public PSystemLogo() {
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final int width = 640;
final int height = 480;
final EmptyImageBuilder builder = new EmptyImageBuilder(width, height, Color.WHITE);
@ -74,7 +76,6 @@ public class PSystemLogo extends AbstractPSystem {
return new ImageDataSimple(im.getWidth(), im.getHeight());
}
// private GraphicStrings getGraphicStrings() throws IOException {
// final UFont font = new UFont("SansSerif", Font.PLAIN, 12);
// final GraphicStrings result = new GraphicStrings(strings, font, HtmlColorUtils.BLACK, HtmlColorUtils.WHITE,
@ -92,5 +93,4 @@ public class PSystemLogo extends AbstractPSystem {
lines.add(line);
}
}

View File

@ -0,0 +1,863 @@
/*
ASCIIMathTeXImg.js
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.
*/
//var AMTcgiloc = ''; //set to the URL of your LaTex renderer
var noMathRender = false;
var config = {
translateOnLoad: true, //true to autotranslate
mathcolor: "", // defaults to back, or specify any other color
displaystyle: true, // puts limits above and below large operators
showasciiformulaonhover: true, // helps students learn ASCIIMath
decimalsign: ".", // change to "," if you like, beware of `(1,2)`!
AMdelimiter1: "`", AMescape1: "\\\\`", // can use other characters
AMusedelimiter2: false, //whether to use second delimiter below
AMdelimiter2: "$", AMescape2: "\\\\\\$", AMdelimiter2regexp: "\\$",
AMdocumentId: "wikitext", // PmWiki element containing math (default=body)
doubleblankmathdelimiter: false // if true, x+1 is equal to `x+1`
}; // for IE this works only in <!-- -->
var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4,
RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,
LEFTRIGHT = 9, TEXT = 10; // token types
var AMsqrt = {input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},
AMroot = {input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY},
AMfrac = {input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY},
AMdiv = {input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX},
AMover = {input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},
AMsub = {input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX},
AMsup = {input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX},
AMtext = {input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT},
AMmbox = {input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT},
AMquote = {input:"\"", tag:"mtext", output:"mbox", tex:null, ttype:TEXT};
var AMsymbols = [
//some greek symbols
{input:"alpha", tag:"mi", output:"\u03B1", tex:null, ttype:CONST},
{input:"beta", tag:"mi", output:"\u03B2", tex:null, ttype:CONST},
{input:"chi", tag:"mi", output:"\u03C7", tex:null, ttype:CONST},
{input:"delta", tag:"mi", output:"\u03B4", tex:null, ttype:CONST},
{input:"Delta", tag:"mo", output:"\u0394", tex:null, ttype:CONST},
{input:"epsi", tag:"mi", output:"\u03B5", tex:"epsilon", ttype:CONST},
{input:"varepsilon", tag:"mi", output:"\u025B", tex:null, ttype:CONST},
{input:"eta", tag:"mi", output:"\u03B7", tex:null, ttype:CONST},
{input:"gamma", tag:"mi", output:"\u03B3", tex:null, ttype:CONST},
{input:"Gamma", tag:"mo", output:"\u0393", tex:null, ttype:CONST},
{input:"iota", tag:"mi", output:"\u03B9", tex:null, ttype:CONST},
{input:"kappa", tag:"mi", output:"\u03BA", tex:null, ttype:CONST},
{input:"lambda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST},
{input:"Lambda", tag:"mo", output:"\u039B", tex:null, ttype:CONST},
{input:"lamda", tag:"mi", output:"lambda", tex:null, ttype:DEFINITION},
{input:"Lamda", tag:"mi", output:"Lambda", tex:null, ttype:DEFINITION},
{input:"mu", tag:"mi", output:"\u03BC", tex:null, ttype:CONST},
{input:"nu", tag:"mi", output:"\u03BD", tex:null, ttype:CONST},
{input:"omega", tag:"mi", output:"\u03C9", tex:null, ttype:CONST},
{input:"Omega", tag:"mo", output:"\u03A9", tex:null, ttype:CONST},
{input:"phi", tag:"mi", output:"\u03C6", tex:null, ttype:CONST},
{input:"varphi", tag:"mi", output:"\u03D5", tex:null, ttype:CONST},
{input:"Phi", tag:"mo", output:"\u03A6", tex:null, ttype:CONST},
{input:"pi", tag:"mi", output:"\u03C0", tex:null, ttype:CONST},
{input:"Pi", tag:"mo", output:"\u03A0", tex:null, ttype:CONST},
{input:"psi", tag:"mi", output:"\u03C8", tex:null, ttype:CONST},
{input:"Psi", tag:"mi", output:"\u03A8", tex:null, ttype:CONST},
{input:"rho", tag:"mi", output:"\u03C1", tex:null, ttype:CONST},
{input:"sigma", tag:"mi", output:"\u03C3", tex:null, ttype:CONST},
{input:"Sigma", tag:"mo", output:"\u03A3", tex:null, ttype:CONST},
{input:"tau", tag:"mi", output:"\u03C4", tex:null, ttype:CONST},
{input:"theta", tag:"mi", output:"\u03B8", tex:null, ttype:CONST},
{input:"vartheta", tag:"mi", output:"\u03D1", tex:null, ttype:CONST},
{input:"Theta", tag:"mo", output:"\u0398", tex:null, ttype:CONST},
{input:"upsilon", tag:"mi", output:"\u03C5", tex:null, ttype:CONST},
{input:"xi", tag:"mi", output:"\u03BE", tex:null, ttype:CONST},
{input:"Xi", tag:"mo", output:"\u039E", tex:null, ttype:CONST},
{input:"zeta", tag:"mi", output:"\u03B6", tex:null, ttype:CONST},
//binary operation symbols
{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST},
{input:"**", tag:"mo", output:"\u2217", tex:"ast", ttype:CONST},
{input:"***", tag:"mo", output:"\u22C6", tex:"star", ttype:CONST},
{input:"//", tag:"mo", output:"/", tex:"/", ttype:CONST, val:true, notexcopy:true},
{input:"\\\\", tag:"mo", output:"\\", tex:"backslash", ttype:CONST},
{input:"setminus", tag:"mo", output:"\\", tex:null, ttype:CONST},
{input:"xx", tag:"mo", output:"\u00D7", tex:"times", ttype:CONST},
{input:"|><", tag:"mo", output:"\u22C9", tex:"ltimes", ttype:CONST},
{input:"><|", tag:"mo", output:"\u22CA", tex:"rtimes", ttype:CONST},
{input:"|><|", tag:"mo", output:"\u22C8", tex:"bowtie", ttype:CONST},
{input:"-:", tag:"mo", output:"\u00F7", tex:"div", ttype:CONST},
{input:"divide", tag:"mo", output:"-:", tex:null, ttype:DEFINITION},
{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST},
{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST},
{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST},
{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST},
{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER},
{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER},
{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST},
{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER},
{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST},
{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER},
{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST},
{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER},
{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST},
{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER},
{input:"overset", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},
{input:"underset", tag:"munder", output:"stackrel", tex:null, ttype:BINARY},
//binary relation symbols
{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST},
{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST},
{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST},
{input:"gt", tag:"mo", output:">", tex:null, ttype:CONST},
{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST},
{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST},
{input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST},
{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST},
{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST},
{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST},
{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST},
{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST},
{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST},
{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST},
{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST},
{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST},
{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST},
{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST},
{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST},
{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST},
{input:"~=", tag:"mo", output:"\u2245", tex:"stackrel{\\sim}{=}", ttype:CONST}, //back hack b/c mimetex doesn't support /cong
{input:"cong", tag:"mo", output:"~=", tex:null, ttype:DEFINITION},
{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST},
{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST},
//logical symbols
{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE},
{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE},
{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST},
{input:"=>", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},
{input:"implies", tag:"mo", output:"=>", tex:null, ttype:DEFINITION},
{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE},
{input:"<=>", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},
{input:"iff", tag:"mo", output:"<=>", tex:null, ttype:DEFINITION},
{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST},
{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST},
{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST},
{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST},
{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST},
{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST}, //mimetex doesn't support
//grouping brackets
{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET, val:true},
{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET, val:true},
{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET, val:true},
{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET, val:true},
{input:"{", tag:"mo", output:"{", tex:"lbrace", ttype:LEFTBRACKET},
{input:"}", tag:"mo", output:"}", tex:"rbrace", ttype:RIGHTBRACKET},
{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT, val:true},
//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT},
{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},
{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},
{input:"<<", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},
{input:">>", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},
{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true},
{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true},
//miscellaneous symbols
{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST},
{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION},
{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION},
{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION},
{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION},
{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST},
{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST},
{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST},
{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST},
{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST},
{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST},
{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST},
{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST},
{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST},
{input:":'", tag:"mo", output:"\u2235", tex:"because", ttype:CONST},
{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST},
{input:"/_\\", tag:"mo", output:"\u25B3", tex:"triangle", ttype:CONST},
{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST, val:true},
{input:"frown", tag:"mo", output:"\u2322", tex:null, ttype:CONST},
{input:"%", tag:"mo", output:"%", tex:"%", ttype:CONST, notexcopy:true},
{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST},
{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST},
{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST},
{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST},
{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST},
{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST},
{input:"square", tag:"mo", output:"\u25A1", tex:"boxempty", ttype:CONST},
{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST},
{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST},
{input:"|~", tag:"mo", output:"\u2308", tex:"lceil", ttype:CONST},
{input:"lceiling", tag:"mo", output:"|~", tex:null, ttype:DEFINITION},
{input:"~|", tag:"mo", output:"\u2309", tex:"rceil", ttype:CONST},
{input:"rceiling", tag:"mo", output:"~|", tex:null, ttype:DEFINITION},
{input:"CC", tag:"mo", output:"\u2102", tex:"mathbb{C}", ttype:CONST, notexcopy:true},
{input:"NN", tag:"mo", output:"\u2115", tex:"mathbb{N}", ttype:CONST, notexcopy:true},
{input:"QQ", tag:"mo", output:"\u211A", tex:"mathbb{Q}", ttype:CONST, notexcopy:true},
{input:"RR", tag:"mo", output:"\u211D", tex:"mathbb{R}", ttype:CONST, notexcopy:true},
{input:"ZZ", tag:"mo", output:"\u2124", tex:"mathbb{Z}", ttype:CONST, notexcopy:true},
{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true, val:true},
{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true, val:true},
{input:"''", tag:"mo", output:"''", tex:null, val:true},
{input:"'''", tag:"mo", output:"'''", tex:null, val:true},
{input:"''''", tag:"mo", output:"''''", tex:null, val:true},
//standard functions
{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER},
{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER},
{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},
{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},
{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},
{input:"arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true},
{input:"arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true},
{input:"arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true},
{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},
{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},
{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},
{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},
{input:"coth", tag:"mo", output:"coth", tex:null, ttype:UNARY, func:true},
{input:"sech", tag:"mo", output:"sech", tex:null, ttype:UNARY, func:true},
{input:"csch", tag:"mo", output:"csch", tex:null, ttype:UNARY, func:true},
{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},
{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},
{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},
{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},
{input:"abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, notexcopy:true, rewriteleftright:["|","|"]},
{input:"norm", tag:"mo", output:"norm", tex:null, ttype:UNARY, notexcopy:true, rewriteleftright:["\\|","\\|"]},
{input:"floor", tag:"mo", output:"floor", tex:null, ttype:UNARY, notexcopy:true, rewriteleftright:["\\lfloor","\\rfloor"]},
{input:"ceil", tag:"mo", output:"ceil", tex:null, ttype:UNARY, notexcopy:true, rewriteleftright:["\\lceil","\\rceil"]},
{input:"Sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},
{input:"Cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},
{input:"Tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},
{input:"Arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true},
{input:"Arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true},
{input:"Arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true},
{input:"Sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},
{input:"Sosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},
{input:"Tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},
{input:"Cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},
{input:"Sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},
{input:"Csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},
{input:"Log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},
{input:"Ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},
{input:"Abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, notexcopy:true, rewriteleftright:["|","|"]},
{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true},
{input:"exp", tag:"mo", output:"exp", tex:null, ttype:UNARY, func:true},
{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST},
{input:"mod", tag:"mo", output:"mod", tex:"text{mod}", ttype:CONST, notexcopy:true},
{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true},
{input:"lcm", tag:"mo", output:"lcm", tex:"text{lcm}", ttype:UNARY, func:true, notexcopy:true},
{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST},
{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST},
{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER},
{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER},
//arrows
{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST},
{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST},
{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST},
{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST},
{input:">->", tag:"mo", output:"\u21A3", tex:"rightarrowtail", ttype:CONST},
{input:"->>", tag:"mo", output:"\u21A0", tex:"twoheadrightarrow", ttype:CONST},
{input:">->>", tag:"mo", output:"\u2916", tex:"twoheadrightarrowtail", ttype:CONST},
{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST},
{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST},
{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST},
{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},
{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST},
{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},
//commands with argument
AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup,
{input:"cancel", tag:"menclose", output:"cancel", tex:null, ttype:UNARY},
{input:"Sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},
{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true},
{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true},
{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true},
{input:"tilde", tag:"mover", output:"~", tex:null, ttype:UNARY, acc:true},
{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true},
{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true},
{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true},
{input:"ubrace", tag:"munder", output:"\u23DF", tex:"underbrace", ttype:UNARY, acc:true},
{input:"obrace", tag:"mover", output:"\u23DE", tex:"overbrace", ttype:UNARY, acc:true},
AMtext, AMmbox, AMquote,
//{input:"var", tag:"mstyle", atname:"fontstyle", atval:"italic", output:"var", tex:null, ttype:UNARY},
{input:"color", tag:"mstyle", ttype:BINARY},
{input:"bb", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"bb", tex:"mathbf", ttype:UNARY, notexcopy:true},
{input:"mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"mathbf", tex:null, ttype:UNARY},
{input:"sf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"sf", tex:"mathsf", ttype:UNARY, notexcopy:true},
{input:"mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY},
{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:"mathbb", ttype:UNARY, notexcopy:true},
{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY},
{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:"mathcal", ttype:UNARY, notexcopy:true},
{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY},
{input:"tt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"tt", tex:"mathtt", ttype:UNARY, notexcopy:true},
{input:"mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY},
{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:"mathfrak", ttype:UNARY, notexcopy:true},
{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY}
];
function compareNames(s1,s2) {
if (s1.input > s2.input) return 1
else return -1;
}
var AMnames = []; //list of input symbols
function AMinitSymbols() {
var i;
var symlen = AMsymbols.length;
for (i=0; i<symlen; i++) {
if (AMsymbols[i].tex && !(typeof AMsymbols[i].notexcopy == "boolean" && AMsymbols[i].notexcopy)) {
AMsymbols.push({input:AMsymbols[i].tex,
tag:AMsymbols[i].tag, output:AMsymbols[i].output, ttype:AMsymbols[i].ttype,
acc:(AMsymbols[i].acc||false)});
}
}
refreshSymbols();
}
function refreshSymbols(){
var i;
AMsymbols.sort(compareNames);
for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input;
}
function newcommand(oldstr,newstr) {
AMsymbols.push({input:oldstr, tag:"mo", output:newstr, tex:null, ttype:DEFINITION});
refreshSymbols();
}
function newsymbol(symbolobj) {
AMsymbols.push(symbolobj);
refreshSymbols();
}
function AMremoveCharsAndBlanks(str,n) {
//remove n characters and any following blanks
var st;
if (str.charAt(n)=="\\" && str.charAt(n+1)!="\\" && str.charAt(n+1)!=" ")
st = str.slice(n+1);
else st = str.slice(n);
for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1);
return st.slice(i);
}
function AMposition(arr, str, n) {
// return position >=n where str appears or would be inserted
// assumes arr is sorted
if (n==0) {
var h,m;
n = -1;
h = arr.length;
while (n+1<h) {
m = (n+h) >> 1;
if (arr[m]<str) n = m; else h = m;
}
return h;
} else
for (var i=n; i<arr.length && arr[i]<str; i++);
return i; // i=arr.length || arr[i]>=str
}
function AMgetSymbol(str) {
//return maximal initial substring of str that appears in names
//return null if there is none
var k = 0; //new pos
var j = 0; //old pos
var mk; //match pos
var st;
var tagst;
var match = "";
var more = true;
for (var i=1; i<=str.length && more; i++) {
st = str.slice(0,i); //initial substring of length i
j = k;
k = AMposition(AMnames, st, j);
if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){
match = AMnames[k];
mk = k;
i = match.length;
}
more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k];
}
AMpreviousSymbol=AMcurrentSymbol;
if (match!=""){
AMcurrentSymbol=AMsymbols[mk].ttype;
return AMsymbols[mk];
}
// if str[0] is a digit or - return maxsubstring of digits.digits
AMcurrentSymbol=CONST;
k = 1;
st = str.slice(0,1);
var integ = true;
while ("0"<=st && st<="9" && k<=str.length) {
st = str.slice(k,k+1);
k++;
}
if (st == config.decimalsign) {
st = str.slice(k,k+1);
if ("0"<=st && st<="9") {
integ = false;
k++;
while ("0"<=st && st<="9" && k<=str.length) {
st = str.slice(k,k+1);
k++;
}
}
}
if ((integ && k>1) || k>2) {
st = str.slice(0,k-1);
tagst = "mn";
} else {
k = 2;
st = str.slice(0,1); //take 1 character
tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi");
}
if (st=="-" && AMpreviousSymbol==INFIX) {
AMcurrentSymbol = INFIX;
return {input:st, tag:tagst, output:st, ttype:UNARY, func:true, val:true};
}
return {input:st, tag:tagst, output:st, ttype:CONST, val:true}; //added val bit
}
function AMTremoveBrackets(node) {
var st;
if (node.charAt(0)=='{' && node.charAt(node.length-1)=='}') {
var leftchop = 0;
st = node.substr(1,5);
if (st=='\\left') {
st = node.charAt(6);
if (st=="(" || st=="[" || st=="{") {
leftchop = 7;
} else {
st = node.substr(6,7);
if (st=='\\lbrace') {
leftchop = 13;
}
}
} else {
st = node.charAt(1);
if (st=="(" || st=="[") {
leftchop = 2;
}
}
if (leftchop>0) {
//st = node.charAt(node.length-7);
st = node.substr(node.length-8);
if (st=="\\right)}" || st=="\\right]}" || st=='\\right.}') {
node = '{'+node.substr(leftchop);
node = node.substr(0,node.length-8)+'}';
} else if (st=='\\rbrace}') {
node = '{'+node.substr(leftchop);
node = node.substr(0,node.length-14)+'}';
}
}
}
return node;
}
/*Parsing ASCII math expressions with the following grammar
v ::= [A-Za-z] | greek letters | numbers | other constant symbols
u ::= sqrt | text | bb | other unary symbols for font commands
b ::= frac | root | stackrel binary symbols
l ::= ( | [ | { | (: | {: left brackets
r ::= ) | ] | } | :) | :} right brackets
S ::= v | lEr | uS | bSS Simple expression
I ::= S_S | S^S | S_S^S | S Intermediate expression
E ::= IE | I/I Expression
Each terminal symbol is translated into a corresponding mathml node.*/
var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol;
function AMTgetTeXsymbol(symb) {
if (typeof symb.val == "boolean" && symb.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);
}
}
function AMTparseSexpr(str) { //parses str and returns [node,tailstr]
var symbol, node, result, i, st,// rightvert = false,
newFrag = '';
str = AMremoveCharsAndBlanks(str,0);
symbol = AMgetSymbol(str); //either a token or a bracket or empty
if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {
return [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);
var texsymbol = AMTgetTeXsymbol(symbol);
if (texsymbol.charAt(0)=="\\" || symbol.tag=="mo") return [texsymbol,str];
else return ['{'+texsymbol+'}',str];
case LEFTBRACKET: //read (expr+)
AMnestingDepth++;
str = AMremoveCharsAndBlanks(str,symbol.input.length);
result = AMTparseExpr(str,true);
AMnestingDepth--;
var leftchop = 0;
if (result[0].substr(0,6)=="\\right") {
st = result[0].charAt(6);
if (st==")" || st=="]" || st=="}") {
leftchop = 6;
} else if (st==".") {
leftchop = 7;
} else {
st = result[0].substr(6,7);
if (st=='\\rbrace') {
leftchop = 13;
}
}
}
if (leftchop>0) {
result[0] = result[0].substr(leftchop);
if (typeof symbol.invisible == "boolean" && symbol.invisible)
node = '{'+result[0]+'}';
else {
node = '{'+AMTgetTeXsymbol(symbol) + result[0]+'}';
}
} else {
if (typeof symbol.invisible == "boolean" && symbol.invisible)
node = '{\\left.'+result[0]+'}';
else {
node = '{\\left'+AMTgetTeXsymbol(symbol) + result[0]+'}';
}
}
return [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.slice(1).indexOf("\"")+1;
else i = 0;
if (i==-1) i = str.length;
st = str.slice(1,i);
if (st.charAt(0) == " ") {
newFrag = '\\ ';
}
newFrag += '\\text{'+st+'}';
if (st.charAt(st.length-1) == " ") {
newFrag += '\\ ';
}
str = AMremoveCharsAndBlanks(str,i+1);
return [newFrag,str];
case UNARY:
str = AMremoveCharsAndBlanks(str,symbol.input.length);
result = AMTparseSexpr(str);
if (result[0]==null) return ['{'+AMTgetTeXsymbol(symbol)+'}',str];
if (typeof symbol.func == "boolean" && symbol.func) { // functions hack
st = str.charAt(0);
if (st=="^" || st=="_" || st=="/" || st=="|" || st=="," || (symbol.input.length==1 && symbol.input.match(/\w/) && st!="(")) {
return ['{'+AMTgetTeXsymbol(symbol)+'}',str];
} else {
node = '{'+AMTgetTeXsymbol(symbol)+'{'+result[0]+'}}';
return [node,result[1]];
}
}
result[0] = AMTremoveBrackets(result[0]);
if (symbol.input == "sqrt") { // sqrt
return ['\\sqrt{'+result[0]+'}',result[1]];
} else if (symbol.input == "cancel") { // cancel
return ['\\cancel{'+result[0]+'}',result[1]];
} else if (typeof symbol.rewriteleftright != "undefined") { // abs, floor, ceil
return ['{\\left'+symbol.rewriteleftright[0]+result[0]+'\\right'+symbol.rewriteleftright[1]+'}',result[1]];
} else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent
//return ['{'+AMTgetTeXsymbol(symbol)+'{'+result[0]+'}}',result[1]];
return [AMTgetTeXsymbol(symbol)+'{'+result[0]+'}',result[1]];
} else { // font change command
return ['{'+AMTgetTeXsymbol(symbol)+'{'+result[0]+'}}',result[1]];
}
case BINARY:
str = AMremoveCharsAndBlanks(str,symbol.input.length);
result = AMTparseSexpr(str);
if (result[0]==null) return ['{'+AMTgetTeXsymbol(symbol)+'}',str];
result[0] = AMTremoveBrackets(result[0]);
var result2 = AMTparseSexpr(result[1]);
if (result2[0]==null) return ['{'+AMTgetTeXsymbol(symbol)+'}',str];
result2[0] = AMTremoveBrackets(result2[0]);
if (symbol.input=="color") {
newFrag = '{\\color{'+result[0].replace(/[\{\}]/g,'')+'}'+result2[0]+'}';
} else if (symbol.input=="root") {
newFrag = '{\\sqrt['+result[0]+']{'+result2[0]+'}}';
} else {
newFrag = '{'+AMTgetTeXsymbol(symbol)+'{'+result[0]+'}{'+result2[0]+'}}';
}
return [newFrag,result2[1]];
case INFIX:
str = AMremoveCharsAndBlanks(str,symbol.input.length);
return [symbol.output,str];
case SPACE:
str = AMremoveCharsAndBlanks(str,symbol.input.length);
return ['{\\quad\\text{'+symbol.input+'}\\quad}',str];
case LEFTRIGHT:
// if (rightvert) return [null,str]; else rightvert = true;
AMnestingDepth++;
str = AMremoveCharsAndBlanks(str,symbol.input.length);
result = AMTparseExpr(str,false);
AMnestingDepth--;
var st = "";
st = result[0].charAt(result[0].length -1);
//alert(result[0].lastChild+"***"+st);
if (st == "|") { // its an absolute value subterm
node = '{\\left|'+result[0]+'}';
return [node,result[1]];
} else { // the "|" is a \mid
node = '{\\mid}';
return [node,str];
}
default:
//alert("default");
str = AMremoveCharsAndBlanks(str,symbol.input.length);
return ['{'+AMTgetTeXsymbol(symbol)+'}',str];
}
}
function AMTparseIexpr(str) {
var symbol, sym1, sym2, node, result;
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 != "/") {
str = AMremoveCharsAndBlanks(str,symbol.input.length);
// if (symbol.input == "/") result = AMTparseIexpr(str); else
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 == "/") AMTremoveBrackets(node);
if (symbol.input == "_") {
sym2 = AMgetSymbol(str);
if (sym2.input == "^") {
str = AMremoveCharsAndBlanks(str,sym2.input.length);
var 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]+'}';
node = node+'^{'+result[0]+'}';
}
if (typeof sym1.func != 'undefined' && sym1.func) {
sym2 = AMgetSymbol(str);
if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) {
result = AMTparseIexpr(str);
node = '{'+node+result[0]+'}';
str = result[1];
}
}
}
return [node,str];
}
function AMTparseExpr(str,rightbracket) {
var symbol, node, result, i, nodeList = [],
newFrag = '';
var 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 == "/") {
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!=undefined) newFrag += node;
} while ((symbol.ttype != RIGHTBRACKET &&
(symbol.ttype != LEFTRIGHT || rightbracket)
|| AMnestingDepth == 0) && symbol!=null && symbol.output!="");
if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {
// if (AMnestingDepth > 0) AMnestingDepth--;
var len = newFrag.length;
if (len>2 && newFrag.charAt(0)=='{' && newFrag.indexOf(',')>0) { //could be matrix (total rewrite from .js)
var right = newFrag.charAt(len - 2);
if (right==')' || right==']') {
var left = newFrag.charAt(6);
if ((left=='(' && right==')' && symbol.output != '}') || (left=='[' && right==']')) {
// Modified by Arnaud Roques
//var mxout = '\\matrix{';
var mxout = '\\begin{matrix}';
var pos = new Array(); //position of commas
pos.push(0);
var matrix = true;
var mxnestingd = 0;
var subpos = [];
subpos[0] = [0];
var lastsubposstart = 0;
var mxanynestingd = 0;
for (i=1; i<len-1; i++) {
if (newFrag.charAt(i)==left) mxnestingd++;
if (newFrag.charAt(i)==right) {
mxnestingd--;
if (mxnestingd==0 && newFrag.charAt(i+2)==',' && newFrag.charAt(i+3)=='{') {
pos.push(i+2);
lastsubposstart = i+2;
subpos[lastsubposstart] = [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[lastsubposstart].push(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.push(len);
var lastmxsubcnt = -1;
if (mxnestingd==0 && pos.length>0 && matrix) {
for (i=0;i<pos.length-1;i++) {
if (i>0) mxout += '\\\\';
if (i==0) {
//var subarr = newFrag.substr(pos[i]+7,pos[i+1]-pos[i]-15).split(',');
if (subpos[pos[i]].length==1) {
var subarr = [newFrag.substr(pos[i]+7,pos[i+1]-pos[i]-15)];
} else {
var subarr = [newFrag.substring(pos[i]+7,subpos[pos[i]][1])];
for (var j=2;j<subpos[pos[i]].length;j++) {
subarr.push(newFrag.substring(subpos[pos[i]][j-1]+1,subpos[pos[i]][j]));
}
subarr.push(newFrag.substring(subpos[pos[i]][subpos[pos[i]].length-1]+1,pos[i+1]-8));
}
} else {
//var subarr = newFrag.substr(pos[i]+8,pos[i+1]-pos[i]-16).split(',');
if (subpos[pos[i]].length==1) {
var subarr = [newFrag.substr(pos[i]+8,pos[i+1]-pos[i]-16)];
} else {
var subarr = [newFrag.substring(pos[i]+8,subpos[pos[i]][1])];
for (var j=2;j<subpos[pos[i]].length;j++) {
subarr.push(newFrag.substring(subpos[pos[i]][j-1]+1,subpos[pos[i]][j]));
}
subarr.push(newFrag.substring(subpos[pos[i]][subpos[pos[i]].length-1]+1,pos[i+1]-8));
}
}
if (lastmxsubcnt>0 && subarr.length!=lastmxsubcnt) {
matrix = false;
} else if (lastmxsubcnt==-1) {
lastmxsubcnt=subarr.length;
}
mxout += subarr.join('&');
}
}
// Modified by Arnaud Roques
// mxout += '}';
mxout += '\\end{matrix}';
if (matrix) { newFrag = mxout;}
}
}
}
str = AMremoveCharsAndBlanks(str,symbol.input.length);
if (typeof symbol.invisible != "boolean" || !symbol.invisible) {
node = '\\right'+AMTgetTeXsymbol(symbol); //AMcreateMmlNode("mo",document.createTextNode(symbol.output));
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 [newFrag,str];
}
function AMTparseAMtoTeX(str) {
AMnestingDepth = 0;
str = str.replace(/(&nbsp;|\u00a0|&#160;)/g,"");
str = str.replace(/&gt;/g,">");
str = str.replace(/&lt;/g,"<");
if (str.match(/\S/)==null) {
return "";
}
return AMTparseExpr(str.replace(/^\s+/g,""),false)[0];
}
AMinitSymbols();
function plantuml(asciiMathInput) {
return AMTparseAMtoTeX(asciiMathInput);
}

View File

@ -1,30 +1,49 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.Graphics2D;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.imageio.ImageIO;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.sourceforge.plantuml.Dimension2DDouble;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import javax.swing.Icon;
public class AsciiMath {
@ -32,10 +51,12 @@ public class AsciiMath {
private static String JAVASCRIPT_CODE;
private final String tex;
static {
try {
final BufferedReader br = new BufferedReader(new InputStreamReader(
AsciiMath.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "AsciiMathParser.js"), "UTF-8"));
AsciiMath.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "ASCIIMathTeXImg.js"), "UTF-8"));
final StringBuilder sb = new StringBuilder();
String s = null;
while ((s = br.readLine()) != null) {
@ -50,79 +71,52 @@ public class AsciiMath {
}
private final Node mathML;
public AsciiMath(String form) throws IOException, ScriptException, ParserConfigurationException,
NoSuchMethodException {
public AsciiMath(String form) throws ScriptException, NoSuchMethodException {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval(JAVASCRIPT_CODE);
final Invocable inv = (Invocable) engine;
final Document dom = createDocument();
mathML = (Node) inv.invokeFunction("plantuml", dom, form);
tex = (String) inv.invokeFunction("plantuml", form);
}
public static void main(String[] args) throws IOException, NoSuchMethodException, ScriptException,
ParserConfigurationException, ClassNotFoundException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
AsciiMath math = new AsciiMath("sum_(i=1)^n i^3=((n(n+1))/2)^2");
PrintWriter pw = new PrintWriter(new File("math2.svg"));
pw.println(math.getSvg());
pw.close();
ImageIO.write(math.getImage(), "png", new File("math2.png"));
}
private Document createDocument() throws ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
return document;
}
private Dimension2D dim;
public String getSvg() throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final Class<?> clConverter = Class.forName("net.sourceforge.jeuclid.converter.Converter");
final Method getInstance = clConverter.getMethod("getInstance");
final Object conv = getInstance.invoke(null);
final Method convert = clConverter.getMethod("convert", Node.class, OutputStream.class, String.class,
Class.forName("net.sourceforge.jeuclid.LayoutContext"));
dim = (Dimension2D) convert.invoke(conv, mathML, baos, "image/svg+xml", getLayout());
return new String(baos.toByteArray());
}
public BufferedImage getImage() throws IOException, ClassNotFoundException, NoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchFieldException {
final Class<?> clConverter = Class.forName("net.sourceforge.jeuclid.converter.Converter");
final Method getInstance = clConverter.getMethod("getInstance");
final Object conv = getInstance.invoke(null);
// final LayoutContext layoutContext = LayoutContextImpl.getDefaultLayoutContext();
final Method render = clConverter.getMethod("render", Node.class,
Class.forName("net.sourceforge.jeuclid.LayoutContext"));
final BufferedImage result = (BufferedImage) render.invoke(conv, mathML, getLayout());
dim = new Dimension2DDouble(result.getWidth(), result.getHeight());
return result;
}
private Object getLayout() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
InvocationTargetException, IllegalArgumentException, NoSuchFieldException, SecurityException {
final Class<?> clLayoutContextIml = Class.forName("net.sourceforge.jeuclid.context.LayoutContextImpl");
final Class<?> clParameter = Class.forName("net.sourceforge.jeuclid.context.Parameter");
final Method getDefaultLayoutContext = clLayoutContextIml.getMethod("getDefaultLayoutContext");
final Object layoutContext = getDefaultLayoutContext.invoke(null);
final Method setParameter = clLayoutContextIml.getMethod("setParameter", clParameter, Object.class);
setParameter.invoke(layoutContext, clParameter.getDeclaredField("SCRIPTSIZEMULTIPLIER").get(null), (float) 2);
return layoutContext;
}
private Dimension2D dimension;
public Dimension2D getDimension() {
return dim;
return dimension;
}
private Icon buildIcon(Color foregroundColor) throws ClassNotFoundException, NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
return new TeXIconBuilder(tex, foregroundColor).getIcon();
}
public String getSvg(Color foregroundColor, Color backgroundColor) throws ClassNotFoundException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, InstantiationException, IOException {
final Icon icon = buildIcon(foregroundColor);
final ConverterSvg converterSvg = new ConverterSvg(icon);
final String svg = converterSvg.getSvg(true, backgroundColor);
dimension = converterSvg.getDimension();
return svg;
}
public BufferedImage getImage(Color foregroundColor, Color backgroundColor) throws ClassNotFoundException,
NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
final Icon icon = buildIcon(foregroundColor);
final BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2 = image.createGraphics();
if (backgroundColor != null) {
g2.setColor(backgroundColor);
g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());
}
icon.paintIcon(null, g2, 0, 0);
return image;
}
public String getLatex() {
return tex;
}
}

View File

@ -0,0 +1,145 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.sourceforge.plantuml.Dimension2DDouble;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class AsciiMathOld {
private static final String ASCIIMATH_PARSER_JS_LOCATION = "/net/sourceforge/plantuml/math/";
private static String JAVASCRIPT_CODE;
static {
try {
final BufferedReader br = new BufferedReader(new InputStreamReader(
AsciiMathOld.class.getResourceAsStream(ASCIIMATH_PARSER_JS_LOCATION + "AsciiMathParser.js"), "UTF-8"));
final StringBuilder sb = new StringBuilder();
String s = null;
while ((s = br.readLine()) != null) {
sb.append(s);
sb.append("\n");
}
br.close();
JAVASCRIPT_CODE = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
private final Node mathML;
public AsciiMathOld(String form) throws IOException, ScriptException, ParserConfigurationException,
NoSuchMethodException {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval(JAVASCRIPT_CODE);
final Invocable inv = (Invocable) engine;
final Document dom = createDocument();
mathML = (Node) inv.invokeFunction("plantuml", dom, form);
}
private Document createDocument() throws ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
return document;
}
private Dimension2D dim;
public String getSvg() throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final Class<?> clConverter = Class.forName("net.sourceforge.jeuclid.converter.Converter");
final Method getInstance = clConverter.getMethod("getInstance");
final Object conv = getInstance.invoke(null);
final Method convert = clConverter.getMethod("convert", Node.class, OutputStream.class, String.class,
Class.forName("net.sourceforge.jeuclid.LayoutContext"));
dim = (Dimension2D) convert.invoke(conv, mathML, baos, "image/svg+xml", getLayout());
return new String(baos.toByteArray());
}
public BufferedImage getImage() throws IOException, ClassNotFoundException, NoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchFieldException {
final Class<?> clConverter = Class.forName("net.sourceforge.jeuclid.converter.Converter");
final Method getInstance = clConverter.getMethod("getInstance");
final Object conv = getInstance.invoke(null);
// final LayoutContext layoutContext = LayoutContextImpl.getDefaultLayoutContext();
final Method render = clConverter.getMethod("render", Node.class,
Class.forName("net.sourceforge.jeuclid.LayoutContext"));
final BufferedImage result = (BufferedImage) render.invoke(conv, mathML, getLayout());
dim = new Dimension2DDouble(result.getWidth(), result.getHeight());
return result;
}
private Object getLayout() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
InvocationTargetException, IllegalArgumentException, NoSuchFieldException, SecurityException {
final Class<?> clLayoutContextIml = Class.forName("net.sourceforge.jeuclid.context.LayoutContextImpl");
final Class<?> clParameter = Class.forName("net.sourceforge.jeuclid.context.Parameter");
final Method getDefaultLayoutContext = clLayoutContextIml.getMethod("getDefaultLayoutContext");
final Object layoutContext = getDefaultLayoutContext.invoke(null);
final Method setParameter = clLayoutContextIml.getMethod("setParameter", clParameter, Object.class);
setParameter.invoke(layoutContext, clParameter.getDeclaredField("SCRIPTSIZEMULTIPLIER").get(null), (float) 2);
return layoutContext;
}
public Dimension2D getDimension() {
return dim;
}
}

View File

@ -1,13 +1,41 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.geom.Dimension2D;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.imageio.ImageIO;
@ -32,26 +60,21 @@ public class AsciiMathSafe {
try {
this.math = new AsciiMath(form);
} catch (Exception e) {
e.printStackTrace();
Log.info("Error parsing " + form);
}
}
public static void main(String[] args) throws IOException {
AsciiMathSafe math = new AsciiMathSafe("sum_(i=1)^n i^3=((n(n+1))/2)^2");
PrintWriter pw = new PrintWriter(new File("math2.svg"));
pw.println(math.getSvg());
pw.close();
ImageIO.write(math.getImage(), "png", new File("math2.png"));
}
private ImageData dimSvg;
public String getSvg() {
public String getSvg(Color foregroundColor, Color backgroundColor) {
try {
final String svg = math.getSvg();
final String svg = math.getSvg(foregroundColor, backgroundColor);
dimSvg = new ImageDataSimple(math.getDimension());
return svg;
} catch (Exception e) {
printTrace(e);
final ImageBuilder imageBuilder = getRollback();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
@ -63,10 +86,11 @@ public class AsciiMathSafe {
}
}
public BufferedImage getImage() {
public BufferedImage getImage(Color foregroundColor, Color backgroundColor) {
try {
return math.getImage();
return math.getImage(foregroundColor, backgroundColor);
} catch (Exception e) {
printTrace(e);
final ImageBuilder imageBuilder = getRollback();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
@ -78,6 +102,14 @@ public class AsciiMathSafe {
}
}
private void printTrace(Exception e) {
System.err.println("Form=" + form);
if (math != null) {
System.err.println("Latex=" + math.getLatex());
}
e.printStackTrace();
}
private ImageBuilder getRollback() {
final TextBlock block = GraphicStrings.createBlackOnWhiteMonospaced(Arrays.asList(form));
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 0, 0,
@ -86,14 +118,15 @@ public class AsciiMathSafe {
return imageBuilder;
}
public ImageData export(OutputStream os, FileFormatOption fileFormat) throws IOException {
public ImageData export(OutputStream os, FileFormatOption fileFormat, Color foregroundColor, Color backgroundColor)
throws IOException {
if (fileFormat.getFileFormat() == FileFormat.PNG) {
final BufferedImage image = getImage();
final BufferedImage image = getImage(foregroundColor, backgroundColor);
ImageIO.write(image, "png", os);
return new ImageDataSimple(image.getWidth(), image.getHeight());
}
if (fileFormat.getFileFormat() == FileFormat.SVG) {
os.write(getSvg().getBytes());
os.write(getSvg(foregroundColor, backgroundColor).getBytes());
return dimSvg;
}
return null;

View File

@ -0,0 +1,121 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.Dimension;
import java.awt.Graphics;
import java.awt.geom.Dimension2D;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.Icon;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
public class ConverterSvg {
private final Icon icon;
public ConverterSvg(Icon icon) {
this.icon = icon;
}
static {
try {
// DefaultTeXFont.registerAlphabet(new CyrillicRegistration());
// DefaultTeXFont.registerAlphabet(new GreekRegistration());
final Class<?> clDefaultTeXFont = Class.forName("org.scilab.forge.jlatexmath.DefaultTeXFont");
final Class<?> clAlphabetRegistration = Class.forName("org.scilab.forge.jlatexmath.AlphabetRegistration");
final Method registerAlphabet = clDefaultTeXFont.getMethod("registerAlphabet", clAlphabetRegistration);
registerAlphabet.invoke(null, Class.forName("org.scilab.forge.jlatexmath.cyrillic.CyrillicRegistration")
.newInstance());
registerAlphabet.invoke(null, Class.forName("org.scilab.forge.jlatexmath.greek.GreekRegistration")
.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
private Dimension dimension;
public String getSvg(boolean fontAsShapes, Color backgroundColor) throws ClassNotFoundException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, InstantiationException, IOException {
// DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
final Class<?> clGenericDOMImplementation = Class.forName("org.apache.batik.dom.GenericDOMImplementation");
final DOMImplementation domImpl = (DOMImplementation) clGenericDOMImplementation.getMethod(
"getDOMImplementation").invoke(null);
final String svgNS = "http://www.w3.org/2000/svg";
final Document document = domImpl.createDocument(svgNS, "svg", null);
// SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document);
final Class<?> clSVGGeneratorContext = Class.forName("org.apache.batik.svggen.SVGGeneratorContext");
final Object ctx = clSVGGeneratorContext.getMethod("createDefault", Document.class).invoke(null, document);
// SVGGraphics2D g2 = new SVGGraphics2D(ctx, fontAsShapes);
final Class<?> clSVGGraphics2D = Class.forName("org.apache.batik.svggen.SVGGraphics2D");
final Graphics g2 = (Graphics) clSVGGraphics2D.getConstructor(clSVGGeneratorContext, boolean.class)
.newInstance(ctx, fontAsShapes);
dimension = new Dimension(icon.getIconWidth(), icon.getIconHeight());
// g2.setSVGCanvasSize(dimension);
g2.getClass().getMethod("setSVGCanvasSize", Dimension.class).invoke(g2, dimension);
if (backgroundColor != null) {
g2.setColor(backgroundColor);
g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());
}
icon.paintIcon(null, g2, 0, 0);
final Writer out = new CharArrayWriter();
final boolean useCSS = true;
// g2.stream(out, useCSS);
g2.getClass().getMethod("stream", Writer.class, boolean.class).invoke(g2, out, useCSS);
out.flush();
out.close();
return out.toString();
}
public Dimension2D getDimension() {
return dimension;
}
}

View File

@ -30,6 +30,7 @@
*/
package net.sourceforge.plantuml.math;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
@ -50,9 +51,11 @@ public class PSystemMath extends AbstractPSystem {
return new DiagramDescriptionImpl("(Math)", getClass());
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
AsciiMathSafe asciiMath = new AsciiMathSafe(math);
return asciiMath.export(os, fileFormat);
return asciiMath.export(os, fileFormat, Color.BLACK, Color.WHITE);
}
public void doCommandLine(String line) {

View File

@ -0,0 +1,68 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.Insets;
import java.lang.reflect.InvocationTargetException;
import javax.swing.Icon;
public class TeXIconBuilder {
private Icon icon;
public TeXIconBuilder(String tex, Color foregroundColor) throws ClassNotFoundException, NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
// TeXFormula formula = new TeXFormula(latex);
final Class<?> clTeXFormula = Class.forName("org.scilab.forge.jlatexmath.TeXFormula");
final Object formula = clTeXFormula.getConstructor(String.class).newInstance(tex);
// TeXIcon icon = formula.new TeXIconBuilder().setStyle(TeXConstants.STYLE_DISPLAY).setSize(20).build();
final Class<?> clTeXIconBuilder = clTeXFormula.getClasses()[0];
final Object builder = clTeXIconBuilder.getConstructors()[0].newInstance(formula);
clTeXIconBuilder.getMethod("setStyle", int.class).invoke(builder, 0);
clTeXIconBuilder.getMethod("setSize", float.class).invoke(builder, (float) 20);
icon = (Icon) clTeXIconBuilder.getMethod("build").invoke(builder);
final int margin = 1;
final Insets insets = new Insets(margin, margin, margin, margin);
icon.getClass().getMethod("setInsets", insets.getClass()).invoke(icon, insets);
icon.getClass().getMethod("setForeground", foregroundColor.getClass()).invoke(icon, foregroundColor);
}
public Icon getIcon() {
return icon;
}
}

View File

@ -43,23 +43,29 @@ import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.DiagramDescriptionImpl;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.graphic.GraphicStrings;
import net.sourceforge.plantuml.donors.PSystemDonors;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockHorizontal;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.graphic.VerticalAlignment;
import net.sourceforge.plantuml.openiconic.data.DummyIcon;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
public class PSystemListOpenIconic extends AbstractPSystem {
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final UDrawable result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE,
getMetadata(), null, 0, 0, null, false);
imageBuilder.setUDrawable(result);
return imageBuilder.writeImageTOBEMOVED(fileFormat, os);
}
private TextBlockBackcolored getGraphicStrings() throws IOException {
private UDrawable getGraphicStrings() throws IOException {
final List<String> lines = new ArrayList<String>();
lines.add("<b>List Open Iconic");
lines.add("<i>Credit to");
@ -73,8 +79,8 @@ public class PSystemListOpenIconic extends AbstractPSystem {
lines.add("<&" + s + "> " + s);
}
br.close();
return GraphicStrings.createBlackOnWhite(lines, null, null, 35);
final List<TextBlock> cols = PSystemDonors.getCols(lines, 7, 0);
return new TextBlockHorizontal(cols, VerticalAlignment.TOP);
}
private InputStream getRessourceAllTxt() {

View File

@ -52,22 +52,24 @@ public class PSystemOpenIconic extends AbstractPSystem {
this.factor = factor;
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final OpenIcon icon = OpenIcon.retrieve(iconName);
// final Dimension2D dim = new Dimension2DDouble(100, 100);
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0,
null, null, null, 5, 5, null, false);
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 5, 5,
null, false);
imageBuilder.setUDrawable(icon.asTextBlock(HtmlColorUtils.BLACK, factor));
return imageBuilder.writeImageTOBEMOVED(fileFormat, os);
// UGraphic2 ug = fileFormat.createUGraphic(dim);
// ug = (UGraphic2) ug.apply(new UTranslate(10, 10));
// // ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK));
// // ug.draw(new URectangle(7, 6));
// icon.asTextBlock(HtmlColorUtils.BLACK, factor).drawU(ug);
// ug.writeImageTOBEMOVED(os, null, 96);
// return new ImageDataSimple(dim);
// UGraphic2 ug = fileFormat.createUGraphic(dim);
// ug = (UGraphic2) ug.apply(new UTranslate(10, 10));
// // ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK));
// // ug.draw(new URectangle(7, 6));
// icon.asTextBlock(HtmlColorUtils.BLACK, factor).drawU(ug);
// ug.writeImageTOBEMOVED(os, null, 96);
// return new ImageDataSimple(dim);
}
// private GraphicStrings getGraphicStrings() throws IOException {

View File

@ -90,7 +90,9 @@ public class PSystemOregon extends AbstractPSystem {
return screen;
}
public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);

View File

@ -39,7 +39,9 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Defines {
import net.sourceforge.plantuml.Log;
public class Defines implements Truth {
private final Map<String, Define> values = new LinkedHashMap<String, Define>();
private final Map<String, Define> savedState = new LinkedHashMap<String, Define>();
@ -48,7 +50,17 @@ public class Defines {
values.put(name, new Define(name, value));
}
public boolean isDefine(String name) {
public boolean isDefine(String expression) {
try {
final EvalBoolean eval = new EvalBoolean(expression, this);
return eval.eval();
} catch (IllegalArgumentException e) {
Log.info("Error in " + expression);
return false;
}
}
public boolean isTrue(String name) {
for (String key : values.keySet()) {
if (key.equals(name) || key.startsWith(name + "(")) {
return true;

View File

@ -0,0 +1,125 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.preproc;
// http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form
public class EvalBoolean {
private final String str;
private int pos = -1;
private char ch;
private final Truth truth;
public EvalBoolean(String str, Truth truth) {
this.str = str;
this.truth = truth;
}
private void nextChar() {
pos++;
if (pos < str.length()) {
ch = str.charAt(pos);
} else {
ch = '\0';
}
}
private boolean eat(char charToEat) {
while (ch == ' ') {
nextChar();
}
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
private boolean parseExpression() {
boolean x = parseTerm();
while (true) {
if (eat('|')) {
eat('|');
x = x | parseTerm();
} else {
return x;
}
}
}
private boolean parseTerm() {
boolean x = parseFactor();
while (true) {
if (eat('&')) {
eat('&');
x = x & parseFactor();
} else {
return x;
}
}
}
private boolean parseFactor() {
if (eat('!')) {
return !(parseFactor());
}
final boolean x;
final int startPos = pos;
if (eat('(')) {
x = parseExpression();
eat(')');
} else if (isIdentifier()) {
while (isIdentifier()) {
nextChar();
}
final String func = str.substring(startPos, pos);
x = truth.isTrue(func);
} else {
throw new IllegalArgumentException("Unexpected: " + (char) ch);
}
return x;
}
private boolean isIdentifier() {
return ch == '_' || Character.isLetterOrDigit(ch);
}
public boolean eval() {
nextChar();
final boolean x = parseExpression();
if (pos < str.length()) {
throw new IllegalArgumentException("Unexpected: " + (char) ch);
}
return x;
}
}

View File

@ -0,0 +1,134 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* 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.preproc;
// http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form
public class EvalMath {
private final String str;
private int pos = -1;
private char ch;
public EvalMath(String str) {
this.str = str;
}
private void nextChar() {
pos++;
if (pos < str.length()) {
ch = str.charAt(pos);
} else {
ch = '\0';
}
}
private boolean eat(int charToEat) {
while (ch == ' ') {
nextChar();
}
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
private double parseExpression() {
double x = parseTerm();
while (true) {
if (eat('+')) {
x += parseTerm();
} else if (eat('-')) {
x -= parseTerm();
} else {
return x;
}
}
}
private double parseTerm() {
double x = parseFactor();
while (true) {
if (eat('*')) {
x *= parseFactor();
} else if (eat('/')) {
x /= parseFactor();
} else {
return x;
}
}
}
private double parseFactor() {
if (eat('+')) {
return parseFactor();
}
if (eat('-')) {
return -parseFactor();
}
final double x;
final int startPos = pos;
if (eat('(')) {
x = parseExpression();
eat(')');
} else if ((ch >= '0' && ch <= '9') || ch == '.') {
while ((ch >= '0' && ch <= '9') || ch == '.')
nextChar();
x = Double.parseDouble(str.substring(startPos, pos));
} else if (ch >= 'a' && ch <= 'z') {
while (ch >= 'a' && ch <= 'z') {
nextChar();
}
final String func = str.substring(startPos, pos);
x = parseFactor();
throw new RuntimeException("Unknown function: " + func);
} else {
throw new RuntimeException("Unexpected: " + (char) ch);
}
return x;
}
public double eval() {
nextChar();
double x = parseExpression();
if (pos < str.length()) {
throw new RuntimeException("Unexpected: " + (char) ch);
}
return x;
}
public static void main(String[] args) {
final EvalMath eval = new EvalMath("33+2*(4+1)");
System.err.println(eval.eval());
}
}

View File

@ -39,9 +39,9 @@ import net.sourceforge.plantuml.command.regex.Pattern2;
class IfManager implements ReadLine {
protected static final Pattern2 ifdefPattern = MyPattern.cmpile("^[%s]*!if(n)?def[%s]+([A-Za-z_][A-Za-z_0-9]*)$");
protected static final Pattern2 elsePattern = MyPattern.cmpile("^[%s]*!else$");
protected static final Pattern2 endifPattern = MyPattern.cmpile("^[%s]*!endif$");
protected static final Pattern2 ifdefPattern = MyPattern.cmpile("^[%s]*!if(n)?def[%s]+(.+)$");
protected static final Pattern2 elsePattern = MyPattern.cmpile("^[%s]*!else[%s]*$");
protected static final Pattern2 endifPattern = MyPattern.cmpile("^[%s]*!endif[%s]*$");
private final Defines defines;
private final ReadLine source;
@ -53,7 +53,7 @@ class IfManager implements ReadLine {
this.source = source;
}
final public CharSequence2 readLine() throws IOException {
final public CharSequence2 readLine() throws IOException {
if (child != null) {
final CharSequence2 s = child.readLine();
if (s != null) {
@ -82,15 +82,9 @@ class IfManager implements ReadLine {
} else {
child = new IfManagerNegatif(source, defines);
}
// child = new IfManager(source, defines, ok ? IfPart.IF :
// IfPart.SKIP);
return this.readLine();
}
// m = endifPattern.matcher(s);
// if (m.find()) {
// return null;
// }
return s;
}

Some files were not shown because too many files have changed in this diff Show More