new text handling in SVG export seems to work

This commit is contained in:
hneemann 2018-02-18 21:21:34 +01:00
parent bf46f84a36
commit c0b17f8f00
3 changed files with 88 additions and 34 deletions

View File

@ -1,11 +1,16 @@
package de.neemann.digital.draw.graphics;
import de.neemann.digital.draw.graphics.text.ParseException;
import de.neemann.digital.draw.graphics.text.Parser;
import de.neemann.digital.draw.graphics.text.formatter.SVGFormatter;
import de.neemann.digital.draw.graphics.text.text.Decorate;
import de.neemann.digital.draw.graphics.text.text.Text;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import static de.neemann.digital.core.element.ElementAttributes.cleanLabel;
/**
* Subclass of {@link GraphicSVG} which creates the correct SVG representation
* of an index if used like "x_0".
@ -38,39 +43,15 @@ public class GraphicSVGIndex extends GraphicSVG {
@Override
public String formatText(String text, Style style) {
text = text.replace('~', '\u00ac');
return formatSVGIndex(escapeXML(formatIndex(cleanLabel(text))));
}
private String formatIndex(String text) {
int p = text.lastIndexOf("_");
if (p > 0) {
text = text.substring(0, p) + "_{" + text.substring(p + 1) + "}";
try {
Text t = new Parser(text).parse();
if (style.getFontStyle() == Font.ITALIC)
t = new Decorate(t, Decorate.Style.MATH);
return SVGFormatter.format(t);
} catch (ParseException e) {
e.printStackTrace();
}
return text;
}
private String formatSVGIndex(String text) {
int p1;
while ((p1 = text.indexOf("_{")) >= 0) {
int p2 = text.indexOf('}', p1);
if (p2 >= 0) {
String ind = text.substring(p1 + 2, p2);
if (ind.length() > 0)
ind = "<tspan style=\"font-size:80%;baseline-shift:sub\">" + ind + "</tspan>";
text = text.substring(0, p1) + ind + text.substring(p2 + 1);
}
}
while ((p1 = text.indexOf("^{")) >= 0) {
int p2 = text.indexOf('}', p1);
if (p2 >= 0) {
String ind = text.substring(p1 + 2, p2);
if (ind.length() > 0)
ind = "<tspan style=\"font-size:80%;baseline-shift:super\">" + ind + "</tspan>";
text = text.substring(0, p1) + ind + text.substring(p2 + 1);
}
}
return text;
}
}

View File

@ -0,0 +1,73 @@
package de.neemann.digital.draw.graphics.text.formatter;
import de.neemann.digital.draw.graphics.text.text.*;
import de.neemann.digital.draw.graphics.text.text.Character;
/**
* The SVG text formatter
*/
public final class SVGFormatter {
private SVGFormatter() {
}
/**
* Formats the given text
*
* @param text the text to format
* @return the formatted string
*/
public static String format(Text text) {
return format(text, false);
}
private static String format(Text text, boolean mathMode) {
if (text instanceof Simple) {
return ((Simple) text).getText();
} else if (text instanceof Blank) {
return " ";
} else if (text instanceof Character) {
return character(((Character) text).getChar());
} else if (text instanceof Decorate) {
Decorate d = (Decorate) text;
switch (d.getStyle()) {
case MATH:
return "<tspan style=\"font-style:italic\">" + format(d.getContent(), true) + "</tspan>";
case OVERLINE:
return "<tspan style=\"text-decoration: overline\">" + format(d.getContent(), mathMode) + "</tspan>";
default:
return format(d.getContent(), mathMode);
}
} else if (text instanceof Index) {
Index i = (Index) text;
String str = format(i.getVar(), true);
if (i.getSubScript() != null)
str += "<tspan style=\"font-size:80%;baseline-shift:sub\">" + format(i.getSubScript(), mathMode) + "</tspan>";
if (i.getSuperScript() != null)
str += "<tspan style=\"font-size:80%;baseline-shift:super\">" + format(i.getSuperScript(), mathMode) + "</tspan>";
return str;
} else if (text instanceof Sentence) {
Sentence s = (Sentence) text;
StringBuilder sb = new StringBuilder();
for (Text t : s)
sb.append(format(t, mathMode));
return sb.toString();
} else return "";
}
private static String character(char aChar) {
switch (aChar) {
case '&':
return "&amp;";
case '<':
return "&lt;";
case '>':
return "&gt;";
case '"':
return "&quot;";
default:
return "" + aChar;
}
}
}

View File

@ -12,7 +12,7 @@ public class GraphicSVGIndexTest extends TestCase {
assertEquals("Z<tspan style=\"font-size:80%;baseline-shift:sub\">0</tspan>", gs.formatText("Z_0", Style.NORMAL));
assertEquals("&lt;a&gt;", gs.formatText("<a>", Style.NORMAL));
assertEquals("¬Z", gs.formatText("~Z", Style.NORMAL));
assertEquals("<tspan style=\"text-decoration: overline\">Z</tspan>", gs.formatText("~Z", Style.NORMAL));
}
}