package org.eclipse.iee.pad.text; import java.awt.Color; import java.io.IOException; import java.io.StringReader; import java.util.Deque; import java.util.LinkedList; import java.util.Map; import org.eclipse.iee.core.document.parser.IPadParser; import org.eclipse.iee.core.document.text.AbstractCompositeNode; import org.eclipse.iee.core.document.text.Document; import org.eclipse.iee.core.document.text.INode; import org.eclipse.iee.core.document.text.Span; import org.eclipse.iee.core.document.text.Text; import org.eclipse.iee.core.document.text.TextStyle; import org.jsoup.Jsoup; import org.jsoup.select.Elements; import org.jsoup.select.NodeVisitor; import org.osgi.service.component.annotations.Component; import org.w3c.css.sac.InputSource; import org.w3c.dom.css.CSSPrimitiveValue; import org.w3c.dom.css.CSSStyleDeclaration; import org.w3c.dom.css.RGBColor; import com.google.common.base.Strings; import com.steadystate.css.parser.CSSOMParser; /** * {@link IPadParser} implementation. Creates instance of text pad. */ @Component public class TextPadParser implements IPadParser { @Override public TextPart create(Map<String, String> padParams, String value) { TextPart textPad = new TextPart(); textPad.setId(padParams.get("id")); Document root = parseDoc(value); textPad.setRoot(root); return textPad; } private Document parseDoc(String value) { Document root = new Document(); org.jsoup.nodes.Document doc = Jsoup.parse(value); final Deque<INode> stack = new LinkedList<>(); stack.add(root); final CSSOMParser parser = new CSSOMParser(); Elements body = doc.getElementsByTag("body"); body.traverse(new NodeVisitor() { @Override public void tail(org.jsoup.nodes.Node node, int depth) { INode n = stack.pop(); AbstractCompositeNode<INode> peek = (AbstractCompositeNode<INode>) stack.peek(); peek.addChild(n); } @Override public void head(org.jsoup.nodes.Node node, int depth) { INode newNode; if (node instanceof org.jsoup.nodes.TextNode) { newNode = new Text().setText(((org.jsoup.nodes.TextNode) node).text()); } else if (node instanceof org.jsoup.nodes.Element) { Span span = new Span(); if (node.hasAttr("style")) { TextStyle style = span.getStyle(); try { CSSStyleDeclaration styleDecl = parser.parseStyleDeclaration(new InputSource(new StringReader(node.attr("style")))); if ("italic".equals(styleDecl.getPropertyValue("font-style"))) { style.setItalic(true); } else { style.setItalic(false); } if ("bold".equals(styleDecl.getPropertyValue("font-weight"))) { style.setBold(true); } else { style.setBold(false); } if (styleDecl.getPropertyValue("font-family") != null) { style.setFont(styleDecl.getPropertyValue("font-family")); } if (!Strings.isNullOrEmpty(styleDecl.getPropertyValue("font-size"))) { style.setFontSize(new Integer(styleDecl.getPropertyValue("font-size"))); } if (!Strings.isNullOrEmpty(styleDecl.getPropertyValue("color"))) { RGBColor rgbColorValue = ((CSSPrimitiveValue)styleDecl.getPropertyCSSValue("color")).getRGBColorValue(); Color fg = new Color( (int) rgbColorValue.getRed().getFloatValue(CSSPrimitiveValue.CSS_NUMBER), (int) rgbColorValue.getGreen().getFloatValue(CSSPrimitiveValue.CSS_NUMBER), (int) rgbColorValue.getBlue().getFloatValue(CSSPrimitiveValue.CSS_NUMBER) ); style.setFgColor(fg); } if (!Strings.isNullOrEmpty(styleDecl.getPropertyValue("background-color"))) { RGBColor rgbColorValue = ((CSSPrimitiveValue)styleDecl.getPropertyCSSValue("background-color")).getRGBColorValue(); Color bg = new Color( (int) rgbColorValue.getRed().getFloatValue(CSSPrimitiveValue.CSS_NUMBER), (int) rgbColorValue.getGreen().getFloatValue(CSSPrimitiveValue.CSS_NUMBER), (int) rgbColorValue.getBlue().getFloatValue(CSSPrimitiveValue.CSS_NUMBER) ); style.setBgColor(bg); } } catch (IOException e) { e.printStackTrace(); } } newNode = span; } else { newNode = new Span(); } stack.push(newNode); } }); return root; } @Override public String getType() { return "Text"; } }